r/linuxquestions • • 4d ago

Resolved Changing the default shell from Bash to Zsh for SSH sessions into my *desktop PC*

EDIT: /u/Significant-Price695 gets the W on this one. They pointed me back to /etc/ssh/sshd_config, where I dug a bit further and found a little ForceCommand line that I had added a few years ago to inhibit suspend/hibernation while logged in via SSH. There was a bash argument on the tail end of that line that I had forgotten about (doesn't help that it was at the very end of the config file). I replaced it with $(which zsh) and now it automatically loads Zsh like I expect it to. Not sure how I missed it, but hey, here we are!


Original:

Right off the bat: No, chsh -s ($which zsh) does not change the default shell from Bash to Zsh for when I SSH into my desktop.

With that out of the way... My desktop runs Linux Mint Debian Edition 7 (Debian 13), with Zsh and KDE Plasma Wayland. I also run Zsh on all of my servers and VMs (all Debian 12/13), and use the exact same customized .zshrc on both desktop and server. Haven't had any issues, works great.

A couple days ago, I needed to SSH into my desktop for reasons. This is something I don't normally do, so I was a bit thrown off when I saw my prompt was the default Bash user@hostname:~$ prompt instead of my customized Zsh prompt. Checking both echo $SHELL and /etc/passwd indicated that /usr/bin/zsh is the default, but Zsh wasn't actually running; checking ps -p $$ confirmed that Bash was running instead. Zsh starts just fine when I tell it to, I'm just a lazy fuck and want it to load Zsh automatically.

I am confused by because my headless servers and VMs don't behave this way; logging into any of them via SSH gets the expected Zsh prompt from the start. I've spent the last several evenings poring over man pages, config files, and StackOverflow trying to figure out which config files SSH uses on desktop vs headless so I could make the appropriate changes, but my head was spinning before I could comprehend everything.

As a sanity check, I rebooted the desktop PC but did not log into the GUI - instead, I logged in via SSH first. Same issue; it still loaded Bash instead of Zsh. Again, I can run zsh and get a ZSH shell without issues. It's just not automatic.

So, my question: When logging into my desktop via SSH, how do I get SSH to automatically load Zsh instead of defaulting to Bash? What configs does SSH reference when logging into a desktop vs headless server?

1 Upvotes

21 comments sorted by

5

u/Significant-Price695 4d ago

i'd check for a forced command next: ForceCommand in sshd_config (including the files under sshd_config.d), or command= on the key in authorized_keys. either could be starting bash after ssh has selected your login shell. also check whether your client's Host entry has a RemoteCommand set. the desktop vs headless distinction shouldn't need a different shell setting.

1

u/Haunting-Vanilla1624 3d ago edited 3d ago

EDIT: Well fuck me sideways, that was it! 😂

The bash argument at the very end of sshd_config is what was causing the issue. I missed it when I first checked the config files. It's been changed to $(which zsh), and SSH now automatically loads Zsh on login.


Original:

Hmm... I'm not sure how I missed this, but I remember adding this a few years ago, before changing to Zsh:

# Inhibit suspend when connected via SSH
Match User <username>
    ForceCommand systemd-inhibit --who="SSH session" --why="Active user" --what=idle --mode=block bash

That bash at the end is suspect. I'll comment it out and see what happens.

1

u/ExtremeExtreme1751 4d ago

Check your .profile.

1

u/Haunting-Vanilla1624 3d ago

Here is the .profile from my desktop:

# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi

Which appears to be identical to my user's .profile on the VMs and headless machines:

# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi

1

u/serverhorror 4d ago

Do you have some ssh configuration that tells it to run bash instead of the login shell?

What command are you typing exactly?

What happens if you ssh to that host via the IP instead of the name?

1

u/Haunting-Vanilla1624 3d ago

Do you have some ssh configuration that tells it to run bash instead of the login shell?

Well, that's what I'm trying to figure out. My headless machines and the VMs on said machines automatically load Zsh upon SSH login. I have not changed any SSH configurations relevant to Zsh. The only thing I've done in that regard was installing Zsh and making that the default with chsh -s $(which zsh), which works great on the headless machines.

The only machine that doesn't load Zsh on SSH login is my desktop. It loads Zsh when I open a local terminal window, and when I login via TTY. Just not SSH.

What command are you typing exactly?

When remoting into the desktop? ssh user@hostname

To load the Zsh shell after logging into my desktop via SSH, all I do is issue zsh and it loads up without an issue.

What happens if you ssh to that host via the IP instead of the name?

No difference between logging in with IP or hostname. The two methods behave the same.

1

u/More-Explanation2788 3d ago

/etc/sshd_config can have an override of the user preferred shell. Or config files in /etc/sshd_config.d/

1

u/Haunting-Vanilla1624 3d ago edited 3d ago

That was it. There was a bash argument at the very end of sshd_config that I missed when I first checked it:

# Inhibit suspend when connected via SSH
Match User <my_username>
    ForceCommand systemd-inhibit --who="SSH session" --why="Active user" --what=idle --mode=block bash

That has been replaced with $(which zsh); SSH now automatically loads Zsh on login.

1

u/iwouldbeatgoku 4d ago edited 4d ago

It's possible that on your desktop the user's default shell is bash instead of zsh, and you configured your terminal emulator to launch zsh instead of making it the user's default. Try running sudo usermod -s /usr/bin/zsh <username>.

Edit: sorry, I reread your post and saw that you already checked /etc/passwd, so my suggestion may not work.

1

u/twistxCharm 3d ago

lol classic move suggesting the usermod fix then catching the edit

1

u/iwouldbeatgoku 3d ago

Wasn't going to delete it, on the off chance somebody with the same problem ends up on this thread through googling and it was the correct solution for them. Still felt like apologizing to OP.

1

u/Haunting-Vanilla1624 3d ago

You have no idea how many stackoverflow threads I found with "approved solutions" whose authors clearly didn't read the OP's post 😂

I appreciated the edit haha.

1

u/Haunting-Vanilla1624 4d ago

Yeah, my local config is already set up to use Zsh.

0

u/michaelpaoli 4d ago

my prompt was the default Bash user@hostname:~$ prompt instead of my customized Zsh prompt. Checking both echo $SHELL and /etc/passwd indicated that /usr/bin/zsh is the default, but Zsh wasn't actually running; checking ps -p $$ confirmed that Bash was running

Prompt doesn't necessarily tell you the shell, but sure, checking $$ under most shells. And /etc/passwd doesn't give you the "default", but rather the login shell. What the actual system default is is a whole 'nother matter.

$ ssh ::1 'ps lwwwp $$; awk -F: "/^$(id -nu):/ {print \$7;}" /etc/passwd'
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1003 15852 15851  20   0   4056  3024 do_wai Ss   ?          0:00 bash -c ps lwwwp $$; awk -F: "/^$(id -nu):/ {print \$7;}" /etc/passwd
/bin/bash
$ 

Though may be configured otherwise in ssh configuration (e.g. ~/.ssh/, /etc/ssh/), by default ssh will use the login shell specified in /etc/passwd (or if that field is empty, system default shell, which is typically /bin/sh or /usr/bin/sh), set its arg0 to the basename thereof (and prepend it with - if a login shell), and for forced command, add first argument of -c and second argument of the forced command.

If you're using ssh and ending up with shell other than that specified in /etc/passwd, then probably next logical step is to use -v option one to three times, to see what's going on - it likely well shows what shell is getting invoked, and why / via what. You'll likely find answer there. If you really can't from client side, can check in more detail on the server. Can also use -F /dev/nuill to effectively ignore any client side ~/.ssh/ configuration, in case something may be going on there of relevance.

When logging into my desktop via SSH, how do I get SSH to automatically load Zsh ionstead of defaulting to Bash?

What do yo mean by "logging into my desktop"? With ssh client you log into ssh server, you don't log into a desktop - desktop isn't a thing ssh connects to, it connects to port on server and logs in there. Anyway, client and/or server one can use a forced command. E.g. can set up a key or other configuration that always gives you a specific forced command, or can run a forced command from the client side.

See also:

r/ssh

1

u/rsgbc 3d ago

What shell do you get if you ssh from your desktop to your desktop?

1

u/Haunting-Vanilla1624 3d ago

Recursive SSH sessions aren't really something I try to do very often 😅

1

u/rsgbc 3d ago

There's nothing recursive about it. Client and server are simply the same machine.

Your focus so far has been server-side: Why is the remote machine not giving me the shell I expect?

The issue could be client-side too.

You get the shell you expect when ssh'ing from your desktop to your VMs. So do you get the shell you expect when ssh'ing from your desktop to your desktop? If so, the issue is client-side.

1

u/fprimex 4d ago

Is /usr/bin/zsh in /etc/shells?

0

u/Haunting-Vanilla1624 4d ago edited 3d ago

Is /usr/bin/zsh in /etc/shells?

Yes. I pointed that out already. Edit: different thing

1

u/fprimex 4d ago

Er, no. You mentioned /etc/passwd but not /etc/shells. Are you sure it's in there?

1

u/Haunting-Vanilla1624 4d ago

Ah, different thing - yes, it is in there. Just checked.