str*_*ika 87 ssh zsh shell-script
我想从 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
Run Code Online (Sandbox Code Playgroud)
这意味着服务器具有此信息。
Gil*_*il' 114
以下是我在我的中使用的标准~/.profile:
SSH_CLIENTor SSH_TTY,则它是一个 ssh 会话。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
Run Code Online (Sandbox Code Playgroud)
(为什么要在 shell 配置而不是会话启动中测试它?)
Cak*_*mox 26
您应该能够通过检查SSH_TTY,SSH_CONNECTION或SSH_CLIENT变量。
miv*_*ivk 10
我只是在 Linux 中遇到了同样的问题,使用 Bash。我首先使用了环境变量 SSH_CONNECTION,但后来意识到如果您su -.
上面的 lastlog 解决方案在su或之后不起作用su -。
最后,我正在使用who am i,如果它是 SSH 连接,它会在末尾显示远程 IP(或主机名)。它也适用于 su 之后。
使用 Bash 正则表达式,这有效:
if [[ $(who am i) =~ \([-a-zA-Z0-9\.]+\)$ ]] ; then echo SSH; else echo no; fi
Run Code Online (Sandbox Code Playgroud)
如果 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
Run Code Online (Sandbox Code Playgroud)
另一种方法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 $?
Run Code Online (Sandbox Code Playgroud)
如果将该函数添加到 .bashrc 中,则可以用作 if is_ssh; then ...
我认为 Gilles 和 Cakemox 的回答很好,但只是为了完整性......
Last login: Fri Mar 18 23:07:28 CET 2011 from max on pts/1
Run Code Online (Sandbox Code Playgroud)
来自pam_lastlog1。
您可以pam_lastlog使用lastlog2命令打印信息,例如
$ lastlog -u mikel  
Username         Port     From             Latest
mikel            tty1                      Fri Jan 28 10:58:10 +1100 2011
Run Code Online (Sandbox Code Playgroud)
对于本地登录,相比
Username         Port     From             Latest
mikel            pts/9    mikel-laptop     Sat Mar 19 11:11:58 +1100 2011
Run Code Online (Sandbox Code Playgroud)
用于 SSH 登录。
在我的系统上,这可以提取它
$ lastlog -u mikel | sed -ne '2{p;q}' | cut -c 27-42
mikel-laptop 
Run Code Online (Sandbox Code Playgroud)
last并且w也可能有帮助,例如
$ 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 
Run Code Online (Sandbox Code Playgroud)
pam_lastlog。lastlog(8)手册页。