Чому SSH-не чекає фонових процесів?


13

Чому це ssh -tне чекає закінчення фонових завдань?

Приклад:

ssh user@example 'sleep 2 &'

Це працює як очікувалося, оскільки ssh повертається через 2 секунди, тоді як

ssh user@example -t 'sleep 2 &'

не чекає sleepзакінчення і повертається негайно.

Хтось може пояснити причину цього? Чи можна ssh -tзачекати, поки всі фонові процеси завершаться, перш ніж повернутися?

Мій випадок використання полягає в тому, що я запускаю сценарій ssh -t, і цей сценарій запускає кілька фонових завдань, які повинні залишатися живими після завершення основного сценарію. З ssh -tцим неможливо поки що.

Відповіді:


22

Без -t, sshdотримують стандартний висновок віддаленої оболонки (і дитина , як sleep) і STDERR через дві труби (а також відправляє введення клієнта через іншу трубу).

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

І eof трапляється тоді, коли дескриптор файлу не відкривається жодним процесом, відкритим на кінці запису труби, що, як правило, відбувається лише тоді, коли всі процеси, які не мали свого stdout, перенаправлені на щось інше, пішли.

При використанні -t, sshdне використовуйте труби. Натомість вся взаємодія (stdin, stdout, stderr) з віддаленою оболонкою та її дітьми здійснюється за допомогою однієї псевдотермінальної пари.

З псевдотермінальною парою, для sshdвзаємодії з головним боком, немає подібного керування eof або будь-якого способу дізнатися, чи все ще існують процеси з FDS, відкритими на підлеглій стороні псевдотермінала, тому він просто чекає припинення процес, в якому він виконав оболонку входу віддаленого користувача, а потім виходить.

Після цього виходу головна частина pty пари закривається, що означає, що pty знищений, тому процеси, керовані веденим, отримають SIGHUP (що за замовчуванням припиняє їх).


1
дякую за ретельну відповідь! Ще одне, що я хотів би знати: чи завершуються всі фонові процеси, коли псевдотермінал закінчується? скрипт, який я починаю, запускає сервіс, який добре працює з ssh. але при використанні ssh -t послуга не запускається. здається, що служба закривається після повернення ssh.
Філіп Меррі

Насправді, існує спосіб для головного боку псевдотерміналу дізнатися, коли всі дескриптори файлів підлеглого були закриті. Це той самий механізм, який спрацьовує справжній термінал, коли всі дескриптори файлів до нього були закриті.
JdeBP


@JdeBP, ви б хотіли розширитись? Я не впевнений, що ти маєш на увазі. Емулятори терміналів AFAICT (як мінімум, xterm та gnome-terminal) не переймаються процесами, які все ще мають Fds, відкриті для підлеглого, коли процес, який вони виконали в оболонці,
Stéphane Chazelas,

@PhilippMurry Ви можете використовувати nohupдля збереження сценарію таким чином. (Ви також можете розглянути можливість запуску тривалих завдань всередині, tmuxщоб ви могли інтерактивно стежити за їх ходом, але файл журналу працює нормально.)
jpaugh,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.