3 minute read

chsh is a small tool that lets you change the default shell for your current user. In order to let any user change their own shell, which is set in /etc/passwd, it needs privileges and is generally setuid root.

I am of the opinion that setuid/setgid binaries are a UNIX legacy that should be deprecated. I will explain the security reasons behind that statement in a future post.

In this “UNIX legacy” series of posts, I am looking at classic setuid binaries and try to find better, safer alternatives for common use cases. In this post, we will look at alternatives to changing your login shell.

Should you change the default shell?

People usually change their default shell because they want to use a modern alternative to Bash (Zsh, fish, Oils, nushell, etc.).

Changing the default shell (especially to a non POSIX or Bash compatible one) might have unintended consequences as some scripts relying on Bash compatibility might not work anymore. There are lots of warnings about this, for example for the fish shell:

On Fedora Atomic Desktops (Silverblue, Kinoite, etc.), your preferred shell may not always be available, notably if you have to reset your overlays for an upgrade, and could lead to an unusable system:

So overall, it is a bad idea to change the default login shell for interactive users.

For non-interactive users or system users, the shell is usually set by the system administrator only and the user itself never needs to change it.

If you are using systemd-homed, then you can change your own shell via the homectl command without needing setuid binaries but for the same reasons as above, it is still not a good idea.

Graphical interface: Use a modern terminal emulator

If you want to use another shell than the default one, you can use the functionality from your graphical terminal emulator to start it by default instead of Bash.

I recommend using the freshly released Prompt (sources) terminal if you are running on Fedora Silverblue or other GNOME related desktops. You can set your preferred shell in the Profiles section of the preferences. It also has great integration for toolbox/distrobox containers. We’re investigating making this the default in a future version of Fedora Silverblue (issue#520).

If you are running on Fedora Kinoite or other KDE related desktops, you should look at Konsole’s profiles features. You can create your own profiles and set the Command to /bin/zsh to use another shell. You can also assign shortcuts to profiles to open them directly a new tab, or use /bin/toolbox enter fedora-toolbox-39 as Command to directly enter a toolbox container for example.

This is obviously not an exhaustive list and other modern terminal emulators also let you specify which command to start.

If your terminal emulator does not allow you to do that, then you can use the alternative from the next section.

Or use a small snippet

If you want to change the default shell for a user on a server, then you can add the following code snippet at the beginning of the user’s ~/.bashrc (example for fish):

# Only trigger if:
# - 'fish' is not the parent process of this shell
# - We did not call: bash -c '...'
# - The fish binary exists and is executable
if [[ $(ps --no-header --pid=$PPID --format=comm) != "fish" && -z ${BASH_EXECUTION_STRING} && -x "/bin/fish" ]]; then
  shopt -q login_shell && LOGIN_OPTION='--login' || LOGIN_OPTION=''
  exec fish $LOGIN_OPTION




Comments are disabled on this blog but feel free to start a discussion with me on Mastodon.
You can also contact me directly if you have feedback.