How to show every installed command-line shell, (i.e. bash, zsh, etc.), with no duplicates, and nothing else, (i.e. no programs that aren't shells)? This code almost works on my Lubuntu system, (which has dash, ksh, zsh, csh and yash), but prints whiptail and fails to print yash:

apropos shell | grep sh | \
  sed 's/ .*//;s/.*/which &/e;/^\/bin\//!d;s/.*/realpath &/e;/^\/bin\//!d' | \
  sort -u | xargs whatis
bash (1)             - GNU Bourne-Again SHell
bsd-csh (1)          - a shell (command interpreter) with C-like syntax
dash (1)             - command interpreter (shell)
ksh93 (1)            - KornShell, a command and programming language
lksh (1)             - Legacy Korn shell built on mksh
mksh (1)             - MirBSD Korn shell
whiptail (1)         - display dialog boxes from shell scripts
zsh5 (1)             - the Z shell
  • 2
    What is "a" shell? Any interactive interpreter, such as Python, can work as a shell in principle. Oct 30, 2016 at 2:30
  • 1
    @immibis, thanks, modified Q to note command-line shell, plus a link showing more instances of same. Re "Any interpreter ... in principle", I'd go with both intent (a shell's author intends to make a shell) and practice, (most of a shell's users regard it as a satisfactory shell), given these criteria, python probably wouldn't apply, (although some users have used python as a shell), the same way that BASIC wouldn't apply, (even though it was the sole "shell" of many early '80s home computers), and so forth. OTOH, the Python superset shell xonsh would fit those criteria.
    – agc
    Oct 30, 2016 at 3:45

2 Answers 2


On FreeBSD, TrueOS/PC-BSD, DragonFly BSD, et al.

The list of approved shells, i.e. shells that the administrator permits users to change their login shell to with the chsh command, is in the conventional /etc/shells file. A simple

cat /etc/shells
gives one the list of approved shells.

However, this is not quite the list of installed shells. Although many third party shells (the operating system itself coming with the Almquist and TENEX C shells) install themselves into /etc/shells when installed from packages or ports, this isn't guaranteed and of course the administrator may have changed /etc/shells so that there is a shell that was installed but that is not approved.

The list of installed shells is not hard to come by, though. As aforementioned, the Almquist and TENEX C shells come with the operating system, as /bin/sh and /bin/tcsh (a.k.a. /bin/csh) respectively. To them one adds the list of shells that are installed from packages. In the FreeBSD package system, all shells are in the shells/ area of the package hierarchy, so one simply uses the pkg tool to query the installed package database:

pkg query "%o %n-%v %c" | awk '/^shells\// {$1="";print $0;}'

This will catch fish, rc, v7sh, heirloom-sh, and suchlike if one has them installed but will also yield a handful of false positives for packages that are in the shells/ hierarchy but that aren't per se shells, such as bash-completion.

Further reading

  • shells/. FreeBSD ports tree. freebsd.org.
  • pkg-query. FreeBSD manual. 2015. freebsd.org.

On OpenBSD

OpenBSD is like FreeBSD, TrueOS et al. with some differences. One still runs

cat /etc/shells
to see the list of approved shells, and there is still the difference between approved and installed shells.

OpenBSD has an older package manager, though, and a different set of shells that come in the operating system itself.

On OpenBSD, the operating system itself comes with the Korn shell (pdksh, specifically) and the C shell (not TENEX C shell) as /bin/sh (a.k.a. /bin/ksh) and /bin/csh (not /bin/tcsh) respectively.

Again, third party shells that one adds to that list are in the shells/ area of the package hierarchy, and the command to find the installed ones is thus

pkg_info -P -A | grep '^shells/'

If you have the sqlports package installed, you can also use sqlite3 to make SQL queries against the /usr/local/share/sqlports database to find installed shell packages.

Further reading

  • shells/. OpenBSD ports tree. ports.su.
  • pkg_info. OpenBSD manual. 2016. openbsd.org.

On Debian, Ubuntu, et al.

Again, the list of approved shells is obtainable with

cat /etc/shells
and again this is not the same as the list of installed shells.

On Debian and Ubuntu, every shell is managed by the package manager. There are no shells that "come with the operating system".

Again, all shell packages are handily marked. APT (the Advanced Packaging Tool) has the notion of "sections" rather than a hierarchy as the BSD ports/packages worlds have, and shell packages are in the Shells section.

There are several tools that can query the package manager's database. I choose aptitude here. One runs

aptitude search '~i~sshells'
which searches for installed (~i) packages in the section (~s) named shells.

This is aptitude's "shorthand" search syntax. The "true" search syntax would be '?installed ?section(shells)' which is somewhat more to type. Furthermore: you can get aptitude to print out more information about each package with its -F command-line option. Consider

aptitude search -F '%p %v %t %d' '~i~sshells'
for example.

Further reading


You could use the /etc/shells file. It should contain a list of valid login shells.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .