Почему SSH -t не ждет фоновых процессов?

Спасибо Francesc Guasch, вы направили нас в нужное русло. Существует проблема с пакетом 7u9 для samba на wheezy, которую, надеюсь, debian найдет и исправит. На данный момент, чтобы исправить доверие к домену, нужно откатить версию samba до предыдущей, которую вы установили. Посмотрите в /var/log/apt/history.log, чтобы найти, какие именно пакеты вы обновили. Вот что я сделал, чтобы решить проблему. Пожалуйста, измените номера версий ниже, чтобы они соответствовали вашим журналам.

apt-get install smbclient=2:3.6.6-6+deb7u7 \
    libwbclient0=2:3.6.6-6+deb7u7 \
    samba-common=2:3.6.6-6+deb7u7 \
    samba=2:3.6.6-6+deb7u7 \
    samba-common-bin=2:3.6.6-6+deb7u7 \
    winbind=2:3.6.6-6+deb7u7 libnss-winbind=2:3.6.6-6+deb7u7
13
22.02.2017, 01:30
3 ответа

Без -t , sshd получает стандартный вывод удаленной оболочки (и дочерние элементы, такие как sleep ) и stderr через два канала ( а также отправляет клиентский ввод через другой канал).

sshd действительно ждет процесса, в котором он запустил оболочку входа пользователя, но также, после того, как этот процесс завершится, ждет eof на конвейере stdout (не на конвейере stderr, по крайней мере, в случае openssh) .

И eof происходит, когда нет дескриптора файла ни одним процессом, открытым на стороне записи канала, что обычно происходит только тогда, когда все процессы, которые не перенаправили свой стандартный вывод на что-то еще, ушли.

Когда вы используете -t , sshd не использует каналы. Вместо этого все взаимодействие (stdin, stdout, stderr) с удаленной оболочкой и ее дочерними элементами выполняется с использованием одной пары псевдотерминалов.

С парой псевдотерминалов для sshd , взаимодействующего с ведущей стороной, нет аналогичной обработки eof, и хотя по крайней мере некоторые системы предоставляют альтернативные способы узнать, есть ли еще процессы с открытыми fds для подчиненная сторона псевдотерминала (см. комментарий @JdeBP ниже), sshd не использует их, поэтому просто ожидает завершения процесса, в котором он выполнил оболочку входа в систему удаленного пользователя и затем уходит.

После этого выхода ведущая сторона пары pty закрывается , что означает, что pty уничтожается, поэтому процессы, контролируемые ведомым устройством, получат SIGHUP (который по умолчанию завершит их).

Правка : последняя часть была неправильной, хотя конечный результат тот же. См. @ pynexj answer для правильного описания того, что именно происходит.

23
29.04.2021, 00:04

Используйте wait :

ssh user@example -t 'sleep 2 & wait'
4
29.04.2021, 00:04

( Чтобы показать разницу в поведении pty между macOS и Linux.)

Пробовал bash -c 'set -m; sleep 5 &'с sexpect на macOS 10.15.6 и Debian 9.6.

В macOS:Чтение отчетов pty/master EOFпосле выхода из родительской оболочки bash.

$ sexpect -sock /tmp/foo.sock -debug spawn -nowait bash -c "set -m; sleep 5 &"
[DEBUG] current winsize: 158x42
[DEBUG] check if another server is using the sockfile
[DEBUG] waiting for the child to open pts
[DEBUG] ready to recv requests
[DEBUG] read(ptm) returned 0 (EOF)
[DEBUG] close(ptm)
[DEBUG] child exited, exiting too (-nowait)
[DEBUG] removing /private/tmp/foo.sock
$

В Debian:Чтение pty/master возвращает -1с ошибкой EIOпосле выхода из дочернего режима сна.

$ sexpect -sock /tmp/foo.sock -debug spawn -nowait bash -c 'set -m; sleep 5 &'
[DEBUG] current winsize: 164x54
[DEBUG] check if another server is using the sockfile
[DEBUG] waiting for the child to open pts
[DEBUG] ready to recv requests
    >>> 5 seconds later >>>
[DEBUG] read(ptm) returned -1: Input/output error (5)
[DEBUG] close(ptm)
[DEBUG] child exited, exiting too (-nowait)
[DEBUG] removing /tmp/foo.sock
$
0
29.04.2021, 00:04

Теги

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