Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm currently setting up a fairly complex bash configuration which shall be used on multiple machines. I try to find out if it is possible to determine whether I'm logged in via SSH or on a local machine. This way I could, for instance, set some aliases depending on that fact. Like aliasing halt to restart since stopping a remote server might not be the best thing to do.

What I know so far is, that the environment variable SSH_CLIENT is set when I logged in via ssh. Unfortunately, this variable is discarded when I start a super user shell with sudo -s. I also know that I can pass a parameter to sudo that instructs sudo to copy all my environment variables to the new shell environment, but if I don't want to do this, is there an other way?

share|improve this question

8 Answers 8

up vote 11 down vote accepted

You could use "w" or "who" command output. When you connect over ssh, they'll show your source IP.

share|improve this answer
1  
Make educated guesses. For example, run ps afx and the TTY for the shell not running ps will be the other login. –  Warner Oct 5 '10 at 13:52
4  
Use who am i. –  Paul Tomblin Oct 5 '10 at 13:53
1  
"uname -n" will give you the hostname –  Hubert Kario Oct 5 '10 at 16:15
1  
The question appears to be more related to extract it from who am i, so that you can determine from there if you're SSHing or not. This works: hostname=$(who am i | cut -f2 -d\( | cut -f1 -d:) –  blueyed Apr 7 '11 at 0:34
1  
or you could be fun and use sed :) as in: who am i | sed 's/.*(\(.*\))/\1/g' –  photoionized Apr 7 '11 at 23:04

You could add SSH_* to env_keep in sudoers so that this can be detected while switched to the other user.

share|improve this answer

If you want to know if you bash shell is directly a child process of sshd (not n>1 layers deep) you can

cat /proc/$PPID/status | head -1 | cut -f2

it should give you sshd or whatever is the parent process name of your current shell.

share|improve this answer

Here is a great answer I found on unix.stackexchange:


  • If one of the variables SSH_CLIENT or SSH_TTY is defined, it's an ssh session.
  • The login shell's parent process can be checked with ps -o comm= -p $PPID. If it is sshd, it's an ssh session.
if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
  SESSION_TYPE=remote/ssh
else
  case $(ps -o comm= -p $PPID) in
    sshd|*/sshd) SESSION_TYPE=remote/ssh;;
  esac
fi
share|improve this answer

I think you want to rethink the way you're thinking of the problem. The question isn't "am I logged in via SSH, because I want to turn off certain commands." It's "am I logged in at the console, because then I will enable certain commands."

share|improve this answer

Yes, as others noted, the info is in the presence of your IP in parentheses in the output of who am i.

You can use Bash regular expressions to detect it:

if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi
share|improve this answer

I've came up with the following, based on tips from others here:

[ -n "$SSH_TTY" ] || [ "$(who am i | cut -f2  -d\( | cut -f1 -d:)" != "" ]
share|improve this answer

Look for your shell's parent cmdline and recurse. Maybe something like the following:

#!/usr/bin/env bash

## Find out how I'm logged in
# Tested on RHEL5.5

PD=${1:-$$}
ME=`basename $0`

## Read the shell's PPID
PAR=`ps --no-headers -p $PD -o ppid`

## CMDLINE can contain stuff like the following:
# /sbin/getty-838400tty4 // logged in at a console
# gnome-terminal         // logged in Gnome Terminal
# -bash                  // in a subshell
# su-                    // we became another user using su
# sshd: jc@pts/1         // logged in over ssh
# login                  // logged in terminal or serial device

eval `python - << __EOF__
import re
f = open("/proc/${PAR}/cmdline", 'r')
ln = f.readline()
if re.search(r'^ssh', ln): 
    print "echo Logged in via ssh"
if re.search(r'getty.*?tty', ln):
    print "echo Logged in console"
if re.search("gnome-terminal", ln):
    print "echo Logged in Gnome"
if re.search(r'^login', ln):
    print "echo Logged in console"
if re.search(r'^-?bash', ln) or re.search(r'^su', ln): 
    print "./$ME $PAR"
f.close()
__EOF__
`

Edited to make it actually work :)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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