How can I detect if the shell is controlled from SSH?
Here are the criteria I use in my ~/.profile
:
- If one of the variables
SSH_CLIENT
orSSH_TTY
is defined, it's an ssh session. - If the login shell's parent process name is
sshd
, it's an ssh session.
if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
SESSION_TYPE=remote/ssh
# many other tests omitted
else
case $(ps -o comm= -p $PPID) in
sshd|*/sshd) SESSION_TYPE=remote/ssh;;
esac
fi
(Why would you want to test this in your shell configuration rather than your session startup?)
You should be able to check via the SSH_TTY
, SSH_CONNECTION
, or SSH_CLIENT
variables.
I just had the same problem in Linux, using Bash. I first used the environment variable SSH_CONNECTION, but then realized that it is not set if you su -
.
The lastlog solution above didn't work either after su
or su -
.
Finally, I am using who am i
, which shows the remote IP (or the hostname) at the end if it's an SSH connection. It also works after su.
Using Bash regular expressions, this works:
if [[ $(who am i) =~ \([-a-zA-Z0-9\.]+\)$ ]] ; then echo SSH; else echo no; fi
If zsh doesn't support regular expressions, the same can be achieved in many different ways with grep, cut, sed, or whatever.
For the curious, below is what I use this for, in root's .bashrc :
# We don't allow root login over ssh.
# To enable root X forwarding if we are logged in over SSH,
# use the .Xauthority file of the user who did su
w=$(who am i)
if [[ $w =~ \([-a-zA-Z0-9\.]+\)$ ]] ; then
olduser=${w/ .*/}
oldhome=$(getent passwd $olduser | cut -d: -f 6)
[ -f "$oldhome/.Xauthority" ] \
&& export XAUTHORITY=$oldhome/.Xauthority
fi
An alternative which also works with su
would be to recursively search for sshd
through the parent processes:
#!/bin/bash
function is_ssh() {
p=${1:-$PPID}
read pid name x ppid y < <( cat /proc/$p/stat )
# or: read pid name ppid < <(ps -o pid= -o comm= -o ppid= -p $p)
[[ "$name" =~ sshd ]] && { echo "Is SSH : $pid $name"; return 0; }
[ "$ppid" -le 1 ] && { echo "Adam is $pid $name"; return 1; }
is_ssh $ppid
}
is_ssh $PPID
exit $?
If the function is added to .bashrc, it can be used as if is_ssh; then ...