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.

Steps to set the default shell in Linux:

  1. Open a terminal session for the user that requires a different default shell.
    $ whoami
    user
  2. Display the current interactive shell from the environment variable.
    $ echo "$SHELL"
    /bin/bash

    The $SHELL variable usually reflects the login shell defined for the account.

  3. Show the login shell recorded in the account database.
    $ getent passwd user
    user:x:1001:1001:,,,:/home/user:/bin/bash

    The last field of the passwd entry indicates the configured login shell.

  4. Install the preferred shell package if it is not already available.
    $ 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.

  5. Install the shell package after the package lists refresh.
    $ 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.

  6. List the shells that are allowed as login shells on the system.
    $ 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.

  7. Confirm the full path to the newly installed shell binary.
    $ command -v zsh
    /usr/bin/zsh
  8. Change the login shell to the new shell path for the current user.
    $ 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.

  9. Close the current terminal session to end the existing shell.

    Logging out of the graphical session or disconnecting any active SSH sessions ensures all new logins use the updated shell.

  10. Start a new terminal or SSH session so the updated shell runs as the default.
    $ sudo -u user -i /bin/zsh -i -c 'echo "$SHELL"'
    /usr/bin/zsh
  11. Verify that the account database entry now references the new login shell.
    $ getent passwd user
    user:x:1001:1001:,,,:/home/user:/usr/bin/zsh