Как убить сессию ssh, связанную с созданием/отключением?
Я использую синергию программы вместе с туннелем ssh
Это работает, мне просто нужно открыть консоль типа этих двух команд:
ssh -f -N -L localhost:12345:otherHost:12345 [email protected]
synergyc localhost
потому что я ленивый, я сделал Bash - Script, который запускается с одним mouseclick на значке:
#!/bin/bash
ssh -f -N -L localhost:12345:otherHost:12345 [email protected]
synergyc localhost
работает также Bash - Script, но теперь я также хочу убить синергию и туннель ssh через один mouseclick, поэтому мне нужно сохранить PIDs синергии и ssh в файл, чтобы убить их позже:
#!/bin/bash
mkdir -p /tmp/synergyPIDs || exit 1
rm -f /tmp/synergyPIDs/ssh || exit 1
rm -f /tmp/synergyPIDs/synergy || exit 1
[ ! -e /tmp/synergyPIDs/ssh ] || exit 1
[ ! -e /tmp/synergyPIDs/synergy ] || exit 1
ssh -f -N -L localhost:12345:otherHost:12345 [email protected]
echo $! > /tmp/synergyPIDs/ssh
synergyc localhost
echo $! > /tmp/synergyPIDs/synergy
Но файлы этого script пусты.
Как получить PID ssh и синергии?
(Я стараюсь избегать комбинаций ps aux | grep ... | awk ... | sed ...
, должен быть более простой способ.)
Ответы
Ответ 1
Ну, я не хочу добавлять и в конце команд, так как соединение будет умирать, если консоль wintow закрыта... поэтому я закончил с ps-grep-awk-sed-combo
ssh -f -N -L localhost:12345:otherHost:12345 [email protected]
echo `ps aux | grep -F 'ssh -f -N -L localhost' | grep -v -F 'grep' | awk '{ print $2 }'` > /tmp/synergyPIDs/ssh
synergyc localhost
echo `ps aux | grep -F 'synergyc localhost' | grep -v -F 'grep' | awk '{ print $2 }'` > /tmp/synergyPIDs/synergy
(вы можете интегрировать grep в awk, но теперь я слишком ленив)
Ответ 2
Краткое резюме: не работает.
Моя первая идея заключается в том, что вам нужно запустить процессы в фоновом режиме, чтобы получить их PID с помощью $!
.
Рисунок, подобный
some_program &
some_pid=$!
wait $some_pid
может делать то, что вам нужно... кроме того, что ssh не будет на переднем плане, чтобы больше спрашивать парольные фразы.
Хорошо, тогда вам может понадобиться что-то другое. ssh -f
, вероятно, порождает новый процесс, который ваша оболочка никогда не сможет узнать из его вызова. В идеале, ssh сам предложит способ записать свой PID в некоторый файл.
Ответ 3
При всем уважении к пользователям pgrep
, pkill
, ps | awk
и т.д. существует намного лучший способ.
Учтите, что если вы полагаетесь на ps -aux | grep ...
, чтобы найти процесс, вы рискуете столкнуться. У вас может быть вариант использования, где это маловероятно, но, как правило, это не путь.
SSH обеспечивает механизм управления и контроля фоновых процессов. Но, как и многие вещи SSH, это "продвинутая" функция, и многие люди (кажется, из других ответов здесь) не знают о ее существовании.
В моем собственном случае у меня есть рабочая станция дома, на которой я хочу оставить туннель, который подключается к прокси-серверу HTTP во внутренней сети моего офиса, и еще один, который дает мне быстрый доступ к интерфейсам управления на co локальные серверы. Вот как вы могли бы создать базовые туннели, инициированные из дома:
$ ssh -fNT -L8888:proxyhost:8888 -R22222:localhost:22 officefirewall
$ ssh -fNT -L4431:www1:443 -L4432:www2:443 colocatedserver
Они вызывают ssh для фона, оставляя туннели открытыми. Но если туннель уйдет, я застрял, и если я захочу его найти, я должен проанализировать список процессов и дома. У меня есть "правильный" ssh (если я случайно запустил несколько из них, которые выглядят аналогичный).
Вместо этого, если я хочу управлять несколькими подключениями, я использую параметр конфигурации SSH ControlMaster
, а также параметр командной строки -O
для управления. Например, со следующим в файле ~/.ssh/config
,
host officefirewall colocatedserver
ControlMaster auto
ControlPath ~/.ssh/cm_sockets/%[email protected]%h:%p
команды ssh выше, когда они запускаются, покидают spoor в ~/.ssh/cm_sockets/
, который затем может предоставить доступ для управления, например:
$ ssh -O check officefirewall
Master running (pid=23980)
$ ssh -O exit officefirewall
Exit request sent.
$ ssh -O check officefirewall
Control socket connect(/home/ghoti/.ssh/cm_socket/[email protected]:22): No such file or directory
И на этом этапе туннель (и управление сеансом SSH) исчез, без необходимости использовать молоток (kill
, killall
, pkill
и т.д.).
Возвращая это к вашему прецеденту...
Вы устанавливаете туннель, через который вы хотите syngergyc
разговаривать с syngergys
на TCP-порту 12345. Для этого я сделал бы что-то вроде следующего.
Добавьте запись в свой ~/.ssh/config
файл:
Host otherHosttunnel
HostName otherHost
User otherUser
LocalForward 12345 otherHost:12345
RequestTTY no
ExitOnForwardFailure yes
ControlMaster auto
ControlPath ~/.ssh/cm_sockets/%[email protected]%h:%p
Обратите внимание, что параметр командной строки -L
обрабатывается с помощью ключевого слова LocalForward
, а строки Control {Master, Path} включены, чтобы убедиться, что у вас есть контроль после того, как туннель установлен.
Затем вы можете изменить свой bash script на что-то вроде этого:
#!/bin/bash
if ! ssh -f -N otherHosttunnel; then
echo "ERROR: couldn't start tunnel." >&2
exit 1
else
synergyc localhost
ssh -O exit otherHosttunnel
fi
Опция -f
заходит в туннель, оставляя сокет на ControlPath для закрытия туннеля позже. Если сбой ssh (что может быть вызвано сетевой ошибкой или ExitOnForwardFailure
), нет необходимости выходить из туннеля, но если это не сработает (else
), запускается synergyc, а затем туннель закрывается после него выходов.
Вы также можете посмотреть, можно ли использовать параметр SSH LocalCommand
для запуска synergyc
справа от вашего конфигурационного файла ssh.
Ответ 4
просто наткнулся на этот поток и хотел упомянуть утилиту linux pidof:
$ pidof init
1
Ответ 5
Вы можете использовать lsof для отображения pid процесса, прослушивающего порт 12345 на localhost:
lsof -t -i @localhost:12345 -sTCP:listen
Примеры:
PID=$(lsof -t -i @localhost:12345 -sTCP:listen)
lsof -t -i @localhost:12345 -sTCP:listen >/dev/null && echo "Port in use"
Ответ 6
Вы можете оставить -f
, что заставляет его запускать его в фоновом режиме, а затем запускать его с помощью eval
и заставлять его на задний план.
Затем вы можете захватить pid
. Не забудьте поставить &
в оператор eval
.
eval "ssh -N -L localhost:12345:otherHost:12345 [email protected] & "
tunnelpid=$!
Ответ 7
Это скорее особый случай для synergyc (и большинства других программ, которые пытаются демонизировать себя). Используя $! будет работать, за исключением того, что synergyc выполняет сценарий clone() во время выполнения, что даст ему новый PID, отличный от того, который bash думал, что он имеет. Если вы хотите обойти это, чтобы вы могли использовать $!, тогда вы можете сказать synergyc, чтобы остаться на поле, а затем фон.
synergyc -f -n mydesktop remoteip &
synergypid=$!
synergyc также выполняет несколько других действий, таких как autorestart, которые вы можете отключить, если вы пытаетесь управлять им.
Ответ 8
Другой вариант - использовать pgrep для поиска PID нового процесса ssh
ssh -fNTL 8073:localhost:873 [email protected]
tunnelPID=$(pgrep -n -x ssh)
synergyc localhost
kill -HUP $tunnelPID
Ответ 9
Вы можете посмотреть на ssh-процедуру, привязанную к вашему локальному порту, используя эту строку:
netstat -tpln | grep 127\.0\.0\.1:12345 | awk '{print $7}' | sed 's#/.*##'
Он возвращает PID процесса, используя порт 12345/TCP на localhost. Поэтому вам не нужно фильтровать все результаты ssh
от ps
.
Если вам просто нужно проверить, связан ли этот порт, используйте:
netstat -tln | grep 127\.0\.0\.1:12345 >/dev/null 2>&1
Возвращает 1
, если никто не связан или 0
, если кто-то слушает этот порт.
Ответ 10
Основываясь на очень хорошем ответе @ghoti, вот более простой script (для тестирования) использование сокетов управления SSH без дополнительной настройки:
#!/bin/bash
if ssh -fN -MS /tmp/mysocket -L localhost:12345:otherHost:12345 [email protected]; then
synergyc localhost
ssh -S /tmp/mysocket -O exit otherHost
fi
synergyc
будет запущен только в том случае, если туннель был успешно установлен, который сам будет закрыт, как только synergyc
вернется.
Хотя в решении отсутствуют правильные сообщения об ошибках.