I want to detect from a shell script (more specifically .zshrc) if it is controlled through SSH. I tried the HOST variable but it's always the name of the computer which is running the shell. Can I access the hostname where the SSH session is coming from? Comparing the two would solve my problem.

Every time I log in there is a message stating the last login time and host:

Last login: Fri Mar 18 23:07:28 CET 2011 from max on pts/1
Last login: Fri Mar 18 23:11:56 2011 from max

This means the server has this information.

7 Answers 7


Here are the criteria I use in my ~/.profile:

  • If one of the variables SSH_CLIENT or SSH_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
# many other tests omitted
  case $(ps -o comm= -p "$PPID") in
    sshd|*/sshd) SESSION_TYPE=remote/ssh;;

(Why would you want to test this in your shell configuration rather than your session startup?)

  • 4
    Worked great thanks! github.com/balupton/dotfiles/commit/…
    – balupton
    Nov 6, 2013 at 6:52
  • 1
    you might want to do this in your shell configuration if you want to enable ssh agent forwarding from your remote shell (since the environment vars need to be set in each shell you want to forward from) unless i'm missing something?
    – underrun
    Apr 14, 2014 at 16:31
  • @underrun I don't understand your point. If you run another shell in the same session, it inherits the environment variables set by .profile. And what does this have to do with agent forwarding? Apr 14, 2014 at 20:41
  • 1
    @underrun If you want to test for the presence of SSH agent forwarding, test for the SSH_AUTH_SOCK variable. But why would you run an SSH agent in that case? Did you mean start an agent if you're logged in without agent forwarding? Why not start an agent if there isn't already one ([ -n "$SSH_AUTH_SOCK" ] || eval $(ssh-agent))? Apr 15, 2014 at 19:11
  • 1
    @Praxeolitic The SSH_* variables are also set in subprocesses of a shell that's at the head of an SSH session, for example if you start a screen session over SSH (you should unset the variables before starting the session if you care). I think the reason for testing the parent process is that I started doing that before sshd defined any environment variables. Mar 7, 2017 at 21:02

You should be able to check via the SSH_TTY, SSH_CONNECTION, or SSH_CLIENT variables.

  • 3
    Also add these to env_keep in sudoers to make it work across su commands:)
    – Thomas G.
    Mar 31, 2016 at 17:00

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

An alternative which also works with su would be to recursively search for sshd through the parent processes:


function is_ssh() {
  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 ...

  • 1
    doesn’t work in remote tmux sessions and also has issues if logged in via IPv6 and no DNS reverse name exists.
    – bene
    Feb 10, 2013 at 16:58
  • @bene: what doesn't work? The regular expression, or does who am i not show your IPv6 address?
    – mivk
    Feb 10, 2013 at 19:08
  • 1) who am i doesn’t return anything in a remote tmux session. 2) IPv6 address might contain colons which your regex doesn’t allow. This might be tricky since who am i contains (:0.0) in X sessions for me (xterm).
    – bene
    Feb 11, 2013 at 15:05
  • @bene: The alternative solution which I just added should also work with IPv6. I don't know about tmux, but it does also work in screen.
    – mivk
    Dec 15, 2013 at 14:54

I think Gilles and Cakemox's answers are good, but just for completeness...

Last login: Fri Mar 18 23:07:28 CET 2011 from max on pts/1

comes from pam_lastlog1.

You can print pam_lastlog information using the lastlog2 command, e.g.

$ lastlog -u mikel  
Username         Port     From             Latest
mikel            tty1                      Fri Jan 28 10:58:10 +1100 2011

for a local login, compared to

Username         Port     From             Latest
mikel            pts/9    mikel-laptop     Sat Mar 19 11:11:58 +1100 2011

for an SSH login.

On my system, this works to extract it

$ lastlog -u mikel | sed -ne '2{p;q}' | cut -c 27-42

last and w could be helpful too, for example

$ TTY=$(tty)
$ last -n 1 ${TTY#/dev/} | sed -ne '1{p;q}'
mikel    pts/12       :0.0             Sat Mar 19 11:29   still logged in 

1 Linux/FreeBSD documentation for pam_lastlog.
2 Linux/FreeBSD lastlog(8) man pages.


Start by taking a look at your environment and finding the right option

printenv|grep SSH

You could hook into many of these environment variables to trigger specific actions based on their presence.


This checks the oposite:

$ ps -o comm= -p $PPID

That's definitely terminal on the computer, not SSH


This is to check all established connection from other user using SSH

netstat | grep ssh
  • This is not at all reliable.
    – DannyNiu
    May 14, 2019 at 8:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.