How can I determine the OS within .bash_profile?

On OSX, uname -s returns Darwin (most Linux uname programs return Linux).

As a general rule (aside from personal use), uname has quirks for different systems. In autoconf, scripts use config.guess, which provides consistent information.

For example in my Debian 7,

x86_64-pc-linux-gnu

and in OSX El Capitan

x86_64-apple-darwin15.5.0

You could use if-then-else statements in the shell, or a case-statement. The latter are more easily maintained, e.g.,

case $(config.guess) in
*linux*)
    DoSomeLinuxStuff
    ;;
*apple-darwin*)
    DoSomeMacStuff
    ;;
esac

Many Linux distributions add information to the output of uname, but this is useful only on a case-by-case basis. There is no standard for the information added.

For my Debian 7:

$ uname -v
#1 SMP Debian 3.2.81-1

while OSX is radically different:

$ uname -v
Darwin Kernel Version 15.5.0: Tue Apr 19 18:36:36 PDT 2016; root:xnu-3248.50.21~8/RELEASE_X86_64

Further reading:

  • config.guess

if [[ $(uname -s) == Linux ]]
then
    doThis
else
    doThat
fi

As an alternate solution, you might try splitting your .bash_profile into a portable part and a system-specific part.

In your main .bash_profile add the following:

if [ -f ~/.bash_profile_local ] ; then
    . ~/.bash_profile_local
fi

Then put any customizations that apply only to a given system into .bash_profile_local on that system. If you have no customizations, you don't have to create the file.

Or, if you wanted to go even further and have pieces shared among some systems but not others, you could do a full-on SYSV-style rc.d directory. In .bash_profile:

if [ -d ~/.bash_profile.d ] ; then
    for f in ~/.bash_profile.d/* ; do
        if [ -f "$f" ] ; then
            . "$f"
        fi
    done
fi

Then create a .bash_profile.d directory, and any files you put in there will be run as if they were part of your .bash_profile.

Tags:

Bash

Osx