Changing the default shell in Linux tailors the command-line environment to match personal workflow and tooling preferences. Shells such as Bash, Zsh, and Fish provide different completion systems, prompt customization, and scripting features, so choosing the right default shell improves productivity and comfort on every login.
On a typical system, the list of valid login shells is stored in /etc/shells, and the chosen shell for each user is recorded in /etc/passwd. Tools such as chsh update the login shell by modifying the account entry, while environment variables like $SHELL or $0 reflect the active shell in a running session. Aligning the configured login shell with the installed binaries in /bin or /usr/bin ensures predictable behavior for interactive sessions and remote logins.
Changing the default shell affects all future logins for that account, including SSH sessions, graphical terminal emulators, and scheduled tasks that rely on the login shell. The new shell must be installed, present in /etc/shells, and referenced by its full path; using an invalid path or an unlisted shell can prevent logins or cause unexpected failures in account management tools.
$ whoami user
$ echo "$SHELL" /bin/bash
The $SHELL variable usually reflects the login shell defined for the account.
$ getent passwd user user:x:1001:1001:,,,:/home/user:/bin/bash
The last field of the passwd entry indicates the configured login shell.
$ sudo apt update Hit:1 http://ports.ubuntu.com/ubuntu-ports noble InRelease Get:2 http://ports.ubuntu.com/ubuntu-ports noble-updates InRelease [126 kB] Hit:3 http://ports.ubuntu.com/ubuntu-ports noble-backports InRelease Hit:4 http://ports.ubuntu.com/ubuntu-ports noble-security InRelease Fetched 126 kB in 2s (52.1 kB/s) Reading package lists... Building dependency tree... Reading state information... 9 packages can be upgraded. Run 'apt list --upgradable' to see them.
On Fedora use sudo dnf install zsh, and on openSUSE use sudo zypper install --no-confirm zsh.
$ sudo apt install --assume-yes zsh Reading package lists... Building dependency tree... Reading state information... The following additional packages will be installed: libgdbm6t64 zsh-common Suggested packages: gdbm-l10n zsh-doc The following NEW packages will be installed: libgdbm6t64 zsh zsh-common 0 upgraded, 3 newly installed, 0 to remove and 9 not upgraded. Need to get 5004 kB of archives. After this operation, 20.8 MB of additional disk space will be used. Get:1 http://ports.ubuntu.com/ubuntu-ports noble/main arm64 libgdbm6t64 arm64 1.23-5.1build1 [34.4 kB] Get:2 http://ports.ubuntu.com/ubuntu-ports noble/main arm64 zsh-common all 5.9-6ubuntu2 [4173 kB] Get:3 http://ports.ubuntu.com/ubuntu-ports noble/main arm64 zsh arm64 5.9-6ubuntu2 [797 kB] Fetched 5004 kB in 3s (1520 kB/s) Selecting previously unselected package libgdbm6t64:arm64. (Reading database ... (Reading database ... 5%(Reading database ... 10%(Reading database ... 15%(Reading database ... 20%(Reading database ... 25%(Reading database ... 30%(Reading database ... 35%(Reading database ... 40%(Reading database ... 45%(Reading database ... 50%(Reading database ... 55%(Reading database ... 60%(Reading database ... 65%(Reading database ... 70%(Reading database ... 75%(Reading database ... 80%(Reading database ... 85%(Reading database ... 90%(Reading database ... 95%(Reading database ... 100%(Reading database ... 13947 files and directories currently installed.) Preparing to unpack .../libgdbm6t64_1.23-5.1build1_arm64.deb ... Unpacking libgdbm6t64:arm64 (1.23-5.1build1) ... Selecting previously unselected package zsh-common. Preparing to unpack .../zsh-common_5.9-6ubuntu2_all.deb ... Unpacking zsh-common (5.9-6ubuntu2) ... Selecting previously unselected package zsh. Preparing to unpack .../zsh_5.9-6ubuntu2_arm64.deb ... Unpacking zsh (5.9-6ubuntu2) ... Setting up libgdbm6t64:arm64 (1.23-5.1build1) ... Setting up zsh-common (5.9-6ubuntu2) ... Setting up zsh (5.9-6ubuntu2) ... Processing triggers for debianutils (5.17build1) ... Processing triggers for libc-bin (2.39-0ubuntu8.6) ...
On Fedora use sudo dnf install zsh, and on openSUSE use sudo zypper install --no-confirm zsh.
$ 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 /bin/zsh /usr/bin/zsh /usr/bin/zsh
Only shells present in /etc/shells should be used as login shells.
$ command -v zsh /usr/bin/zsh
$ sudo chsh -s /usr/bin/zsh user
Configuring a non-existent or wrong shell path can prevent successful logins for the account until corrected by an administrator.
The second argument to chsh selects which user account is modified.
Logging out of the graphical session or disconnecting any active SSH sessions ensures all new logins use the updated shell.
$ sudo -u user -i /bin/zsh -i -c 'echo "$SHELL"' /usr/bin/zsh
$ getent passwd user user:x:1001:1001:,,,:/home/user:/usr/bin/zsh