Home / Alt manpages / remove-shell(8)

  • remove-shell(8)
  • Admin command
  • linux

Safely Remove a Login Shell with remove-shell

You will remove one or more exact entries from /etc/shells, verify the resulting list, and keep a recovery copy in case an account or service still expects the shell. Allow about five minutes for a single entry, plus time to check any users or automation that rely on it. The examples use the installed Debianutils 5.17build1 package on Ubuntu 24.04.

1. Check the command and the current list

remove-shell is an administrative command installed at /usr/sbin/remove-shell. It edits the system list of valid login shells. Reading the list does not require elevated privileges:

$ command -v remove-shell
/usr/sbin/remove-shell
$ cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/usr/bin/sh
/bin/bash
/usr/bin/bash
/bin/rbash
/usr/bin/rbash
/usr/bin/dash
/usr/bin/screen
/usr/bin/tmux
/bin/false

Your list can differ. Treat the exact pathname as significant. The command removes matching lines, not a shell by its descriptive name. Do not remove an entry until you know which accounts, services or tools use it as a login shell.

2. Check who would be affected

Look for accounts whose configured shell is the entry you plan to remove. This is a read-only check:

$ shell_to_remove=/usr/bin/screen
$ awk -F: -v shell="$shell_to_remove" '$7 == shell {print $1 ":" $7}' /etc/passwd

No output means that /etc/passwd has no account with that exact shell. It does not prove that scripts, service units or external identity management do not refer to it. Also check local service configuration and your change records before removing a shell used by automation.

Removing a line from /etc/shells can affect programs that use the file to decide whether a shell is valid for login or account changes. It does not delete the shell executable and it does not change an account's configured shell by itself.

3. Back up the file before changing it

Use an explicit backup and inspect it before proceeding. This needs elevated privileges because /etc/shells is normally owned by root:

$ sudo cp --preserve=all /etc/shells /etc/shells.remove-shell.bak
$ sudo cmp -s /etc/shells /etc/shells.remove-shell.bak
$ printf 'backup matches\n'
backup matches

The backup name is deliberately separate from the live file. Keep it until the affected login or service path has been tested. If you need to undo the change later, restore it with sudo cp --preserve=all /etc/shells.remove-shell.bak /etc/shells, then verify the restored contents.

4. Remove the exact shell entry

Pass the shell pathname as an argument. This operation requires root privileges and changes the live file:

$ sudo remove-shell /usr/bin/screen

The command normally prints nothing and returns success. It removes an exact line matching the supplied argument. The installed script also checks the normalised pathname, so a path that resolves to the same target can match an entry written with a different equivalent path. It does not remove partial matches or comments.

You can provide several shell names in one invocation, but review each one first:

$ sudo remove-shell /usr/bin/screen /usr/bin/tmux

Do not use shell expansion or an unreviewed value from user input here. A mistaken argument can remove a valid entry, and the command does not ask for confirmation.

5. Verify the result and temporary files

Confirm that the removed entry is absent and that the file remains readable:

$ grep -Fqx '/usr/bin/screen' /etc/shells
$ printf 'status: %s\n' "$?"
status: 1
$ test -r /etc/shells && echo '/etc/shells is readable'
/etc/shells is readable
$ test ! -e /etc/shells.tmp && test ! -e /etc/shells.tmp2 && echo 'temporary files absent'
temporary files absent

The first status of 1 is the expected result from grep: the exact line was not found. The command's temporary files are /etc/shells.tmp and /etc/shells.tmp2. They should normally be cleaned up when the operation finishes. If either remains, stop and inspect it before running the command again. An interrupted or concurrent run can leave a temporary file containing useful recovery information.

6. Test the dependent path

Test the account or service that motivated the change, using its normal maintenance procedure. For an account, check its configured shell and perform a controlled login test. For a service, use its documented status and health checks. Do not test by locking out a production user.

If the command fails because another instance is running or a previous run was interrupted, do not delete the temporary file blindly. Read /etc/shells.tmp, compare it with /etc/shells and the backup, and resolve the overlap during a maintenance window. If the removal causes a login or service failure, restore the backup, verify the target entry is present again, and investigate before retrying:

$ sudo cp --preserve=all /etc/shells.remove-shell.bak /etc/shells
$ grep -Fqx '/usr/bin/screen' /etc/shells && echo 'entry restored'
entry restored

Done means

  • You checked the installed command and the current /etc/shells.
  • You checked accounts and services before removing the exact entry.
  • You made a preserved backup before using sudo remove-shell.
  • The target line is absent, the file is readable, and temporary files are gone.
  • The affected login or service path was tested, or the backup is ready for an immediate restore.