Shell Environment – Is $SHELL Variable Only for Interactive Shells?

execposixshell

I see two possible uses for the SHELL environment variable:

  • It can be used to specify the interactive shell the user wants to use, and/or
  • it can be used by processes to execute other commands with, replacing the command in the usual /bin/sh -c "..." idiom.

If it were only used for the former, it could be something very weird (e.g. ipython), if it shall also be used for the latter, it needs to provide a basic form of POSIX compatibility, e.g. understand the -c parameter and keep the environment intact (which is surprisingly tricky).

The POSIX standard is not very explicit here, it just writes.

This variable shall represent a pathname of the user's preferred command language interpreter. If this interpreter does not conform to the Shell Command Language in the Shell and Utilities volume of IEEE Std 1003.1-2001, Chapter 2, Shell Command Language, utilities may behave differently from those described in IEEE Std 1003.1-2001.

Is the second use actually common and/or valid, and hence something to worry about if I set SHELL to something strange?

Best Answer

None of the POSIX C APIs use the SHELL environment variable explicitly. The system and popen function must call a program called sh. A few utilities (e.g. ex, mailx, …) must use $SHELL, but always to execute user-supplied code; make explicitly ignores $SHELL.

The section on environment variables allows utilities, but not C APIs (“system interfaces”) to have a different behavior if $SHELL doesn't comply with POSIX sh.

In practice, SHELL is set to the user's login shell, which may or may not be POSIX-compatible. Zsh and fish are popular alternatives. I've been using zsh for a decade on various Unix variants, and I don't remember any system utility failing. I have seen the occasional sloppily written code calling $SHELL instead of sh to execute sh scripts. This is pretty rare and need not deter you from setting SHELL to whatever you like.

In short, yes, SHELL is your favorite interactive shell, and applications receive no guarantee of what syntax it accepts, or even whether it accepts a -c option.