как я могу определить, управляется ли shell из ssh?

<p>я хочу определить из сценария shell (точнее, .zshrc), управляется ли он через ssh. я пробовал переменную host, но это всегда имя компьютера, на котором работает shell. могу ли я получить доступ к имени хоста, откуда идет сеанс ssh? сравнение этих двух вопросов решило бы мою проблему.</p><p>каждый раз, когда я вхожу, появляется сообщение с указанием времени последнего входа в систему и хоста:</p><pre><code>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 </code></pre><p>это означает, что сервер имеет эту информацию.</p>

<p>вот критерии, которые я использую в своем <code>~/.profile</code>:</p><ul> <li>если одна из переменных <code>ssh\_client</code> или <code>ssh\_tty</code> определено, это сессия ssh.</li> <li>если имя родительского процесса в оболочке входа в систему <code>sshd</code>, это сеанс ssh.</li> </ul><pre><code>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 </code></pre><p>(почему вы хотите проверить это в своей конфигурации shell, а не при запуске сеанса?)</p>

<p>вы должны быть в состоянии проверить через <code>ssh\_tty</code>, <code>ssh\_connection</code>, или <code>ssh\_client</code> переменные.</p>

<p>у меня просто была такая же проблема в linux с использованием bash. сначала я использовал переменную окружения ssh\_connection, но потом понял, что она не установлена, если вы <code>su -</code>.</p><p>решение lastlog выше не работало ни после <code>su</code>, ни <code>su -</code>.</p><p>наконец, я использую <code>who am i</code>, который показывает удаленный ip (или имя хоста) в конце, если это соединение ssh. это также работает после su.</p><p>используя регулярные выражения bash, это работает:</p><pre><code>if [[ $(who am i) =~ ([-a-za-z0-9.]+)$ ]] ; then echo ssh; else echo no; fi </code></pre><p>если zsh не поддерживает регулярные выражения, то же самое может быть достигнуто разными способами с помощью grep, cut, sed или чего-либо еще.</p><p>для любопытных, вот что я использую в root'е .bashrc:</p><pre><code> # 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 </code></pre><p>альтернативой, которая также работает с <code>su</code>, будет рекурсивный поиск <code>sshd</code> через родительские процессы:</p><pre><code>#!/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 $? </code></pre><p>если функция добавлена в .bashrc, ее можно использовать как <code>if is\_ssh; then ...</code></p>

<p>начните с изучения вашей среды и поиска правильного варианта</p><pre><code>printenv|grep ssh ssh\_client=192.168.1.xxx ssh\_connection=192.168.1.xxx ssh\_tty=/dev/ttys021 </code></pre><p>вы можете подключиться ко многим из этих переменных среды, чтобы инициировать конкретные действия в зависимости от их присутствия.</p>