Chci zjistit ze skriptu Shell (konkrétně .zshrc), zda je ovládán pomocí SSH. Zkusil jsem proměnnou Host, ale je to vždy název počítače, na kterém běží prostředí. Mohu získat přístup k názvu hostitele, ze kterého pochází relace SSH? Porovnání těchto dvou problémů by vyřešilo můj problém.
Při každém přihlášení se zobrazí zpráva, která uvádí poslední čas přihlášení a 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
To znamená, že server má tyto informace.
Zde jsou kritéria, která používám ve svém ~/.profile
:
SSH_CLIENT
nebo SSH_TTY
je definováno, jedná se o ssh relaci.sshd
, jedná se o relaci 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
(Proč byste to chtěli vyzkoušet v konfiguraci Shell místo spuštění relace?)
Měli byste být schopni zkontrolovat pomocí SSH_TTY
, SSH_CONNECTION
nebo SSH_CLIENT
proměnné.
Právě jsem měl stejný problém v Linuxu pomocí Bash. Nejprve jsem použil proměnnou prostředí SSH_CONNECTION, ale pak jsem si uvědomil, že není nastavena, pokud su -
.
Řešení lastlog výše nefungovalo ani po su
nebo su -
.
Nakonec používám who am i
, která na konci zobrazuje vzdálenou IP (nebo název hostitele), pokud se jedná o připojení SSH. Funguje to i po su.
Pomocí pravidelných výrazů Bash to funguje:
if [[ $(who am i) =~ \([-a-zA-Z0-9\.]+\)$ ]] ; then echo SSH; else echo no; fi
Pokud zsh nepodporuje regulární výrazy, toho samého lze dosáhnout mnoha různými způsoby pomocí grepu, střihu, sedu nebo cokoli jiného.
Pro zvědavce, níže je to, pro co to používám, v 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
fi
Alternativou, která také pracuje s su
, by bylo rekurzivní hledání sshd
prostřednictvím nadřazených procesů:
#!/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 $?
Pokud je funkce přidána do .bashrc, lze ji použít jako if is_ssh; then ...
Začněte tím, že se podíváte na své prostředí a najdete tu správnou volbu
printenv|grep SSH
SSH_CLIENT=192.168.1.xxx
SSH_CONNECTION=192.168.1.xxx
SSH_TTY=/dev/ttys021
Mohli byste se připojit k mnoha z těchto proměnných prostředí a vyvolat konkrétní akce na základě jejich přítomnosti.