Как завершить удаленно названный “хвост-f”, когда соединение закрывается?

При использовании GNOME 3 можно попытаться установить расширение индикатора рабочей области.

24
01.06.2014, 19:00
2 ответа

В

ssh host tail -f file

Клиент ssh подключается к серверу sshd на хосте через TCP-соединение. sshd запускает tail -f с перенаправлением его stdout в канал. sshd считывает то, что приходит с другого конца канала, и инкапсулирует это в протокол sshd для отправки клиенту ssh . (с rshd , tail stdout был бы непосредственно сокетом, но sshd добавляет шифрование и может мультиплексировать несколько потоков (например, для порта / агента / X11) / tunnel redirection, stderr) для одного TCP-соединения, поэтому приходится прибегать к каналам).

Когда вы нажимаете CTRL-C, SIGINT отправляется клиенту ssh . В результате ssh умирает. После смерти TCP-соединение закрывается. И поэтому на хосте умирает sshd . tail не уничтожается, но его стандартный вывод теперь представляет собой канал без считывателя на другом конце. Итак, в следующий раз, когда он что-то напишет на свой стандартный вывод, он получит SIGPIPE и умрет.

В:

ssh -t host 'tail -f file'

Это то же самое, за исключением того, что связь между sshd и tail осуществляется через псевдотерминал, а не через канал. Стандартный вывод tail является подчиненным псевдотерминалом (например, / dev / pts / 12 ), и все, что tail записывает, есть чтение на стороне мастера (возможно, модифицированной дисциплиной tty line) с помощью sshd и отправляется в инкапсулированном виде клиенту ssh .

На стороне клиента с помощью -t , ssh переводит терминал в режим raw . В частности, это отключает канонический режим терминала и обработку сигналов терминала.

Итак, когда вы нажимаете Ctrl + C , вместо того, чтобы дисциплина клиентской линии терминала отправляла SIGINT в задание ssh , оно просто отправляет ^ C при подключении к sshd и sshd записывает, что ^ C на главную сторону удаленного терминала. И линейная дисциплина удаленного терминала отправляет SIGINT в хвост хвост . Затем tail умирает, и sshd завершает работу и закрывает соединение, а ssh завершает работу (если он не занят переадресацией портов и т. Д.).

Кроме того, с -t , если клиент ssh умирает (например, если вы вводите ~. ), соединение закрывается и sshd умирает. В результате в хвост будет отправлено SIGHUP.

Обратите внимание, что использование -t имеет побочные эффекты. Например, с настройками терминала по умолчанию символы \ n преобразуются в \ r \ n , и в зависимости от удаленной системы может произойти многое другое, поэтому вы можете захотеть выдать stty -opost (для отключения постобработки вывода) на удаленном хосте, если этот вывод не предназначен для терминала:

$ ssh  localhost 'echo x' | hd
00000000  78 0a                                             |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000  78 0d 0a                                          |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000  78 0a                                             |x.|
00000002

Другой недостаток использования -t / - tt заключается в том, что stdout и stderr не различаются на клиенте. И stdout, и stderr удаленной команды будут записаны в stdout клиента ssh :

$ ssh localhost ls /x  | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1
33
27.01.2020, 19:41

Вам необходимо распределение терминала на удаленной стороне:

ssh -t user@remote_host tail -f /some/file

или даже

ssh -tt user@remote_host tail -f /some/file
11
27.01.2020, 19:41

Теги

Похожие вопросы