Завершение сеанса SSH, выполняемое bash script
У меня есть script Я могу запустить локально для удаленного запуска сервера:
#!/bin/bash
ssh [email protected] <<EOF
nohup /path/to/run.sh &
EOF
echo 'done'
После запуска nohup он зависает. Мне нужно нажать ctrl-c, чтобы выйти из script.
Я попытался добавить явный выход в конец этого документа и использовать аргумент "-t" для ssh. Ничего не работает. Как сделать этот script выход немедленно?
EDIT: клиент OSX 10.6, сервер Ubuntu.
Ответы
Ответ 1
Я думаю, проблема заключается в том, что nohup не может перенаправлять вывод, когда вы входите из ssh, он перенаправляет только на nohup.out, когда он думает, что он подключен к терминалу, и я верю в stdin, что вы, с -t
.
Обходной путь может заключаться в том, чтобы перенаправить вывод самостоятельно, а затем клиент ssh может отключиться - он не дожидается завершения потока. Что-то вроде:
nohup /path/to/run.sh > run.log &
(Это работало для меня в простой тесте, подключаемом к серверу Ubuntu от клиента OS X.)
Ответ 2
Проблема может заключаться в том, что...
... ssh is respecting the POSIX standard when not closing the session
if a process is still attached to the tty.
Следовательно, решение может заключаться в отсоединении stdin
команды nohup
от tty:
nohup /path/to/run.sh </dev/null &
Смотрите: SSH висит на выходе при использовании nohup
Еще один подход может заключаться в использовании ssh -t -t
для принудительного распределения псевдо-tty, даже если stdin
не является терминалом.
man ssh | less -Ip 'multiple -t'
ssh -t -t [email protected] <<EOF
nohup /path/to/run.sh &
EOF
Смотрите: BASH создайте подпрограмму для SSH и продолжите с потоком программы
Ответ 3
Перенаправление stdin удаленного хоста из документа здесь при вызове ssh
без явной команды приводит к сообщению: Pseudo-terminal will not be allocated because stdin is not a terminal.
Чтобы избежать этого сообщения, используйте переключатель ssh
-T
, чтобы сообщить удаленному хосту, нет необходимости выделять псевдотерминал или явно указывать команду (например, /bin/sh
) для удаленного хоста для выполнения команды, предоставленные здесь документом.
Если для ssh
задана явная команда, по умолчанию используется no оболочка входа в форму псевдотерминала, i. е. при указании команды не будет обычного сеанса входа в систему (см. man ssh
).
Без команды, указанной для ssh
, с другой стороны, по умолчанию создается псевдо-tty для интерактивного сеанса входа на удаленном хосте.
- ssh [email protected] <<EOF
+ ssh -T [email protected] <<EOF
+ ssh [email protected] /bin/bash <<EOF
Как правило, ssh -t
или даже ssh -t -t
следует использовать, только если есть команды, которые ожидают, что stdin/stdout будет терминалом (например, top
или vim
), или если необходимо убить удаленная оболочка и ее дети, когда команда клиента ssh
завершает выполнение (см. команда ssh неожиданно продолжается в другой системе после завершения ssh).
Насколько я могу судить, единственный способ объединить команду ssh
, которая не выделяет команду pseudo-tty и nohup
, которая записывает на nohup.out
на удаленном хосте, должна позволить nohup
выполнить в псевдотерминале не, созданный механизмом ssh
. Это можно сделать с помощью команды script
, например, и избегать сообщения tcgetattr: Inappropriate ioctl for device
.
#!/bin/bash
ssh localhost /bin/sh <<EOF
#0<&- script -q /dev/null nohup sleep 10 1>&- &
#0<&- script -q -c "nohup sh -c 'date; sleep 10 1>&- &'" /dev/null # Linux
0<&- script -q /dev/null nohup sh -c 'date; sleep 10 1>&- &' # FreeBSD, Mac OS X
cat nohup.out
exit 0
EOF
echo 'done'
exit 0
Ответ 4
Вы пробовали выход 0 в конце?