/etc/shells is and isn't
In traditional Unix,
/etc/shells has only one true purpose: it
lists programs that
chsh will let you change your shell to (if
it lets you do anything). Before people are tempted to make other
programs use this file for something else, it is important to
understand the limits of
/etc/shells. These include but are
not limited to:
- Logins may have
/etc/passwdentries that list other shells. For example, back when restricted shells were popular it was extremely common to not list them in
/etc/shellsso you couldn't accidentally
chshyourself into a restricted shell and then get stuck.
Some but not all programs have used the absence of a shell from
/etc/shellsas a sign that it is a restricted shell (or not a real shell at all) and they should restrict a user with that shell in some way. Other programs have used different tests, such as matching against specific shell names or name prefixes.
(It's traditional for the FTP daemon to refuse access for accounts that do not have a shell that's in
/etc/shellsand so this is broadly accepted. Other programs are on much thinner ice.)
- On the other hand, sometimes you can find restricted shells
/etc/shells; a number of systems (Ubuntu and several FreeBSD versions) include
rbash, the restricted version of Bash, if it's installed.
- Not all normal shells used in
/etc/passwdor simply installed on the system necessarily appear in
/etc/shellsfor various reasons. In practice there are all sorts of ways for installed shells to fall through the cracks. Of course this makes them hard to use as your login shell (since you can't
chshto them), but this can be worked around in various ways.
For example, our Ubuntu systems have
/bin/ksh(and some people use them as their login shells) but neither are in
- The (normal and unrestricted) shell someone's actually using isn't
necessarily in either
/etc/passwdentry. Unix is flexible and easily lets you use
$SHELLand some dotfile hacking to switch basically everything over to running your own personal choice of shell, per my entry on using an alternate shell.
(Essentially everything on Unix that spawns what is supposed to be your interactive shell has been clubbed into using
$SHELL, partly because the code to use
$SHELLis easier to write than the code to look up someone's
/etc/passwdentry to find their official login shell. This feature probably came into Unix with BSD Unix, which was basically the first Unix to have two shells.)
- Entries in
/etc/shellsdon't necessarily exist.
- Entries in
/etc/shellsare not necessarily shells. Ubuntu 14.04 lists
- Not all systems even have an
/etc/shells. Solaris and derivatives such as Illumos and OmniOS don't.
In the face of all of this, most programs should simply use
and assume that it is what the user wants and/or what the sysadmin
wants the user to get. It's essentially safe to assume that
always exists, because it is part of the long-standing standard
Unix login environment. As a corollary, a program
should not change
$SHELL unless it has an excellent reason to
Note particularly that a user's
$SHELL not being listed in
/etc/shells means essentially nothing. As outlined above, there
are any number of non-theoretical ways that this can and does happen
on real systems that are out there in the field. As a corollary
your program should not do anything special in this case unless it
has a really strong reason to do so, generally a security-related
reason. Really, you don't even want to look at
sudo or the like.
(This entry is sadly brought to you by a program getting this wrong.)