В настоящее время я настраиваю довольно сложную конфигурацию bash, которая будет использоваться на нескольких машинах. Я пытаюсь выяснить, можно ли определить, вошел ли я в систему через SSH или на локальном компьютере. Таким образом, я мог бы, например, установить некоторые псевдонимы в зависимости от этого факта. Как алиасинг halt
к restart
поскольку остановка удаленного сервера может быть не лучшим решением.
На данный момент я знаю, что переменная среды SSH_CLIENT
устанавливается, когда я входил в систему через ssh. К сожалению, эта переменная отбрасывается, когда я запускаю оболочку суперпользователя с sudo -s
. Я также знаю, что могу передать sudo параметр, который инструктирует sudo скопировать все переменные моей среды в новую среду оболочки, но если я не хочу этого делать, есть ли другой способ?
Вы можете использовать вывод команды «w» или «who». Когда вы подключаетесь по ssh, они покажут ваш исходный IP.
Вот отличный ответ, который я нашел на unix.stackexchange:
SSH_CLIENT
или SSH_TTY
определен, это сеанс ssh.ps -o comm= -p $PPID
. Если это 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
Вы могли бы добавить SSH_*
к env_keep
в sudoers
чтобы это можно было обнаружить при переключении на другого пользователя.
Если вы хотите знать, является ли оболочка bash напрямую дочерним процессом sshd (а не n> 1 уровня в глубину), вы можете
cat / proc / $ PPID / status | голова -1 | вырезать -f2
это должно дать вам sshd
или любое другое имя родительского процесса вашей текущей оболочки.
Я думаю, вы хотите переосмыслить то, как вы думаете о проблеме. Вопрос не в том, «вошел ли я через SSH, потому что хочу отключить определенные команды». Это «я вошел в систему с консоли, потому что тогда я активирую определенные команды».
Да, как отмечали другие, информация находится в присутствии вашего IP-адреса в круглых скобках в выводе who am i
.
Вы можете использовать регулярные выражения Bash, чтобы обнаружить это:
if [[ $(who am i) =~ \([0-9\.]+\)$ ]]; then echo SSH; else echo no; fi
Я придумал следующее, основываясь на советах других здесь.
Он использует переменную для кеширования - я использую ее в своей теме оболочки.
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
}
Источник: is_ssh
в https://github.com/blueyed/oh-my-zsh/blob/master/themes/blueyed.zsh-theme#L51-63.
Найдите командную строку и рекурсию родительской оболочки. Может быть что-то вроде следующего:
#!/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__
`
Отредактировано, чтобы он действительно работал :)
Все остальные ответы работают, если вы находитесь на первом уровне входа в систему. Но если после входа в систему вы запускаете su или sudo (в моем случае, чтобы переключиться на учетную запись пользователя без оболочки по соображениям безопасности, мне пришлось запустить: sudo su - <userid> -s / bin / bash -l), их решение терпит неудачу.
Ниже приводится универсальное решение; используя 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
Это делает ключевое предположение: процесс входа в систему не будет иметь управляющего TTY; ты, наверное, хочешь проверить, если ты иметь контрольный TTY перед запуском этого кода (который, исходя из ваших требований, в любом случае, вероятно, является безопасной ставкой).
Код выполняет итерацию вверх по дереву процессов, пока не найдет процесс, у которого нет управляющего TTY. $initiator_name
будет именем этого процесса (например, «sshd»).
Если вы не используете функцию X11Forward. Возможно, самый простой способ проверить это через
echo $DISPLAY
Если вы входите через SSH без X11Forward, он обычно пуст, в противном случае, как :1