This is "Can linux work without a shell?" but focussing purely on the mechanics of removing shells without the distractions in that other question.

Consider the same system as there: Ubuntu Linux Server LTS version 16 with bespoke systems comprising compiled binaries running as systemd services, without any end user (or indeed administrator) login.

How does one remove shells? What would be the results of doing so? Of removing the Bourne Again shell? Of removing /bin/sh? How much could such a system still run?

Note that this question is not concerned with why one might want to do this, with terminals, with how to secure a system, or with commands that one can run from shells. The focus here is on shells, the mechanism of removal, and the consequences.


This is quite complex to consider. To start with:

  • The POSIX standard a.k.a. the Single Unix Specification, provides a guarantee that a conformant system will have a program invokable as sh that implements a specific Shell Language. On any given real system, sh will actually be one of the real shells, such as the Z shell, Almquist shell, Korn shell, Bourne Again shell, and so forth; usually recognizing that it has been invoked by the name sh and operating in a POSIX mode.
  • Over a decade ago, the Debian and Ubuntu communities worked hard to eliminate the dependencies of various parts of the operating system upon extensions provided by the Bourne Again shell even in its POSIX mode. Scripts that specified #!/bin/sh as their interpreter were required not to rely upon so-called Bashisms, and conversely scripts that did rely upon Bashisms had to explicitly state the Bourne Again shell as their interpreter and not sh.
  • The systemd people set out as one of their goals back in 2011 the elimination of the use of shell scripts as part of system and service management.

How one removes shells is easy, sort of. One removes packages such as ash, bash, posh, mksh, pdksh, tcsh, dash, and so forth; using a package management tool such as aptitude. The hard part is that two of these are marked as "essential" — dash and bash —, meaning that other packages can assume their presence without explicitly declaring a dependency on them, and it is non-trivial to remove them as the package manager will, intentionally, require you to jump through extra hoops to confirm that you really do want to remove them.

The trouble comes with the consequences of doing that.

  • Thanks to the work of the Debian and Ubuntu people, there are now scripts that explicitly declare #!/bin/bash as their script interpreter. Such scripts will fail to work if the Bourne Again shell is removed, even if one retains the Debian Almquist shell.
  • Scripts that rely upon a POSIX conformant shell will fail to work if the Debian Almquist shell is removed.
  • Compiled programs that rely upon a POSIX conformant shell will fail to work if the Debian Almquist shell is removed. Such programs do things such as call the system() library function, or explicitly execvpe() the sh utility.

As a result:

  • The applications programs may fail to work. Yes, they are written in a compiled language and aren't shell scripts. That does not stop applications programmers from quickly forking and executing the odd shell process here and there.
  • System programs may fail to work. For the same reason.
  • System programs may fail to work for the reason that they are actually shell scripts.
    • The elimination of shell scripts from the startup and shutdown processes is not total, by a long chalk. Many services are still controlled by van Smoorenburg rc scripts, which will fail if there is no sh to interpret them. Run

      systemctl list-units
      All of the services that you see with "LSB:" or "SYSV:" at the starts of their descriptions need a shell interpreter in order to work. Similarly, programs such as rabbitmq-server or mysqld_safe that are sometimes (ab)used as services are in fact shell scripts.
    • Many ancillary and utility programs are shell scripts. Debian's /lib/systemd/systemd-sysv-install is, just for one example. Others include /usr/sbin/service, /usr/sbin/invoke-rc.d, and even /bin/fgrep.
  • Rescue and emergency mode bootstrap will not work. Both rescue.service and emergency.service (as of the version of systemd that is in Ubuntu 16) use /bin/sh.

Further reading

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.