我目前正在build立一个相当复杂的bashconfiguration,它将被用在多台机器上。 我试图找出是否有可能确定我是通过SSH还是本地机器login。 例如,我可以根据这个事实设置一些别名。 像别名halt restart因为停止远程服务器可能不是最好的事情。
我所知道的是,当我通过sshlogin时,环境variablesSSH_CLIENT被设置。 不幸的是,当我用sudo -s启动一个超级用户shell时,这个variables被丢弃了。 我也知道,我可以传递一个参数给sudo,它指示sudo将所有的环境variables复制到新的shell环境中,但是如果我不想这样做,还有其他方法吗?
你可以使用“w”或“who”命令输出。 当你通过SSH连接,他们会显示你的源IP。
您可以在sudoers添加SSH_*到env_keep ,以便在切换到另一个用户时检测到。
我在unix.stackexchange上find了一个很好的答案:
SSH_CLIENT或SSH_TTY ,则它是一个ssh会话。 ps -o comm= -p $PPID来检查loginshell的父进程。 如果是sshd ,那是一个ssh会话。 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
如果你想知道你的bash shell是否直接是sshd的subprocess(不是n> 1层深),你可以
cat / proc / $ PPID / status | 头-1 | 切-f2
它应该给你sshd或者你当前shell的父进程名称。
我想你想重新思考你正在考虑这个问题的方式。 问题不是“我是否通过SSHlogin,因为我想closures某些命令。” 这是“我login控制台,因为那么我将启用某些命令。”
是的,正如其他人所指出的那样,这个信息是在你的知识产权出现在who am i是who am i的输出的括号里的。
你可以使用Bash正则expression式来检测它:
if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi
基于这里其他人的build议,我提出了以下几点。
它使用一个variables进行caching – 我在我的shell主题中使用它。
is_ssh() { (( $+SSH_CLIENT )) && return if ! (( $+_ZSH_IS_SSH )); then # "who am i" displays current user from utmp(5). This will be empty for # a "normal" terminal. With Konsole, it is ":0" for display :0, # for ssh it is the hostname and with tmux sth like "tmux(PID).ID". local whoami="$(who am i)"} local host="${whoami#*\(*}" [[ -n $host && $host != tmux* && $host != :* ]] _ZSH_IS_SSH=$? fi return $_ZSH_IS_SSH }
来源: https : is_ssh中的is_ssh 。
寻找你的shell的父亲cmdline并recursion。 也许像下面这样:
#!/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__ `
编辑,使其实际工作:)
所有其他答案工作,如果你在第一级login。 但是,如果一旦login,运行“su”或“sudo”(在我的情况下,出于安全原因切换到没有shell的用户帐户,我必须运行: sudo su – <userid> -s / bin / bash – l) ,他们的解决scheme失败了。
以下是一个通用解决scheme; 使用pstree,你检查sshd作为父母。
if pstree -p | egrep --quiet --extended-regexp ".*sshd.*\($$\)"; then echo "I am remote." else echo "I am local." fi
这是egrep的输出,当–quiet被移除时。 它显示了与远程连接相匹配的整个层次结构。
| |-sshd(18599)---sshd(18603)---bash(18604)---sudo(18823)---bash(18824)-+-egrep(22417)
请记住,这个答案是非常非常特定于Linux的。
parent_pid=$$ while [[ -z "${tty_bits-}" || $tty_bits -ne 0 ]]; do read initiator_name parent_pid tty_bits < <( awk '{ print substr($2, 2, length($2) - 2) " " $4 " " $7 }' /proc/$parent_pid/stat ) done echo $initiator_name
这是一个关键假设:login过程不会有控制TTY; 你可能想在运行这个代码之前检查一下你是否有一个TTY的控制权(根据你的要求,反正可能是一个安全的赌注)。
代码向上遍历进程树,直到find没有控制TTY的进程。 $initiator_name将是这个进程的名字(例如“sshd”)。