11

I've got a rather extensive selection of dotfiles thats been kept in a git repo for the longest time - I just maintain a separate branch of code for bsd-isms (for instance, on Linux, to get colored ls output you do ls --color=auto, but on BSD-likes including Mac OS, it's ls -g).

This has started to become unwieldy since I have to make the change, then merge branches and deal with conflict resolution every time I touch my shell's rc file. Figure the proper way to handle this would be to drop the git branching, and just have my rc file determine what kind of OS its on, and then source an appropriate addon script for the aliases.

Problem is, I have no idea how to do this.

How do I tell if I'm on Linux or BSD from within a script or shell rc file?

uname won't really work since then I have to write a bunch of logic for the various flavors of systems out there. Mac says Darwin, FreeBSD, etc, when I'm more interested in the underlying type of OS since that will impact what particular set of tools I'm dealing with. For my example above, am I using bsd ls or GNU ls?

Keltari
  • 75,447
Karu
  • 4,922

2 Answers2

15

This Stack Overflow answer by Nicolas Martyanoff provides a complete solution. I tweaked it to use the newer syntax mentioned in the comments.

Determine the OS:

platform='unknown'
unamestr=$(uname)
if [ "$unamestr" = 'Linux' ]; then
   platform='linux'
elif [ "$unamestr" = 'FreeBSD' ]; then
   platform='freebsd'
fi

Choose the right flags for ls:

if [ "$platform" = 'linux' ]; then

   alias ls='ls --color=auto'

elif [ "$platform" = 'freebsd' ]; then

   alias ls='ls -G'

fi
John Bensin
  • 1,645
0

Leaving aside the platform detection (correctly done via uname), it is not just the flags that need to be picked correctly but also the path to the executable.

Calling just ls -G means give me any alias/function/executable-found-in-$PATH and run it with the flag -G. That alias/function/executable might or might not be BSD on a BDS OS, might or might not follow BDS arguments, might or might not be the exact same version that you expect, etc.

For that reason, one would use the full path to the built-in executable that has a really high chance (fiddle with system-level is not as common as fiddling with aliases/functions/$PATH) of following the OS: /bin/ls -G.