我想从 shell 脚本(更具体地说是 .zshrc)中检测它是否是通过 SSH 控制的。我尝试了 HOST 变量,但它始终是运行 shell 的计算机的名称。我可以访问 SSH 会话来源的主机名吗?比较两者可以解决我的问题。
每次登录时都会出现一条消息,说明上次登录时间和主机:
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
这意味着服务器拥有此信息。
答案1
以下是我在我的 中使用的标准~/.profile
:
- 如果定义了其中一个变量
SSH_CLIENT
或,则它是一个 ssh 会话。SSH_TTY
- 如果登录 shell 的父进程名称是
sshd
,则它是一个 ssh 会话。
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
(为什么要在 shell 配置中而不是会话启动中测试它?)
答案2
您应该能够通过SSH_TTY
、SSH_CONNECTION
或SSH_CLIENT
变量进行检查。
答案3
我刚刚在 Linux 中使用 Bash 时遇到了同样的问题。我首先使用了环境变量 SSH_CONNECTION,但后来意识到如果你su -
.
su
上面的 Lastlog 解决方案在或 之后都不起作用su -
。
最后,我使用who am i
,如果是 SSH 连接,它会在末尾显示远程 IP(或主机名)。 su 之后也有效。
使用 Bash 正则表达式,可以实现以下效果:
if [[ $(who am i) =~ \([-a-zA-Z0-9\.]+\)$ ]] ; then echo SSH; else echo no; fi
如果 zsh 不支持正则表达式,则可以使用 grep、cut、sed 等以多种不同方式实现相同目的。
出于好奇,下面是我在 root 的 .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
另一种可行的方法是通过父进程su
递归搜索:sshd
#!/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 $?
如果将该函数添加到.bashrc中,则可以用作if is_ssh; then ...
答案4
首先查看您的环境并找到正确的选择
printenv|grep SSH
SSH_CLIENT=192.168.1.xxx
SSH_CONNECTION=192.168.1.xxx
SSH_TTY=/dev/ttys021
您可以连接其中许多环境变量,以根据它们的存在触发特定操作。