The most common problem caused by misuse of shell startup files is that if you define environment variables in .bashrc
as opposed to .profile
, they are not defined in applications that are not launched from a shell in a terminal but rather from a GUI menu.
Defining environment variables from .bashrc
is generally not a good idea, but that's primarily because it's generally useless as the variables should already have been set at login time. It can cause a problem in practice if you (or an application) have deliberately changed the value of a variable (e.g. PATH
) in a program and you launch a shell from that program and expect the setting to have remained the same.
You can avoid the problem of environment variables being reset by defining a “sentinel” value, and not defining anything if the sentinel value is set:
if [ -z "$JMLANE_PROFILE_READ" ]; then
export ...
export JMLANE_PROFILE_READ=1
fi
Another problem caused by terminals starting login shells is that there are things that should only be done once when you log in, for example starting a password agent (e.g. ssh-agent
), or initiating a session (e.g. running startx
in certain circumstances). The sentinel variable avoids these issues.
A shell inside a terminal is always interactive. As long as you source .bashrc
from .bash_profile
when the shell is interactive, you don't need to worry about the terminal starting a login shell.
An additional wart of bash's startup file handling is that .bashrc
is read by non-interactive shells invoked by rshd or sshd. For example, when you do rsync somefile host.example.com:
, if your login shell on host.example.com
is bash, you can use .bashrc
there to set the path to include rsync
. You can tell you're in this situation because .bashrc
is read from a non-interactive shell.
## .bashrc
if [[ $- != *i* ]]; then
# either .bashrc was executed explicitly or this is a noninteractive rsh/ssh session
fi
This is a very simplified answer, but it's basically accurate.
The commands that don't work on the Mac terminal are programs that the Mac doesn't have. You can find equivalents for most of them, but apt-get
is the Ubuntu package manager so you won't find it on OS X. As far as I know, OS X doesn't even have a package manager.
Best Answer
bash
is a superset ofsh
ie. everything you can do insh
you can do inbash
.Bash has more features (branching, builtins, arrays) making script easier to write. Some later *nix'es have
/bin/sh
as a link to/bin/bash
For a full explanation of what here's a tutorial