Использование SSH для удаленного запуска процесса

18

Я написал скрипт, который я использую для отправки и развертывания новой службы на нескольких машинах, находящихся под моим контролем, и для выполнения процесса я использую ssh для удаленного запуска процесса. К сожалению, всякий раз, когда я использую SSH для запуска процесса, команда SSH никогда не возвращается, в результате чего скрипт останавливается.

Команда указывается как: ssh $ user @ $ host "/ root / command &". Всякий раз, когда я запускаю простые команды, такие как ps или who, команда SSH возвращается немедленно, однако, когда я пытаюсь запустить процесс, она не возвращается. Я пробовал такие хитрости, как завершение процесса в простой сценарий bash, который запускает процесс и затем завершается, однако при этом также зависает команда SSH (даже если сценарий bash отображает сообщение об успешном завершении и завершается нормально).

Кто-нибудь знает, что вызывает такое поведение, и как я могу получить команду SSH, чтобы вернуться, как только процесс был запущен?

Спасибо за ваши идеи!

rmrobins
источник
Отправьте точную командную строку, которую вы используете ... опустите пароли / имена пользователей / IP-адреса
Джозеф Керн,
ssh $ SSH_USER @ $ HOST_ADDR "/ root / AppName &"
rmrobins
Следует отметить, что я настроил ключи SSH, поэтому нет необходимости использовать пароли для запуска команд на удаленных системах.
rmrobins
@rmrobins, очень хороший шаг - установка аутентификации с открытым ключом.
Ник

Ответы:

28

SSH соединяет stdin, stdout и stderr удаленной оболочки с вашим локальным терминалом, чтобы вы могли взаимодействовать с командой, которая выполняется на удаленной стороне.

Как побочный эффект, он будет продолжать работать до тех пор, пока эти соединения не будут закрыты, что происходит только тогда, когда удаленная команда и все ее дочерние элементы (!) Завершены (потому что дочерние элементы, которые запускаются символом «&», наследуют std * от своих родительский процесс и держать его открытым).

Так что вам нужно использовать что-то вроде

ssh user@host "/script/to/run < /dev/null > /tmp/mylogfile 2>&1 &"

<,> И 2> & 1 перенаправляют stdin / stdout / stderr из вашего терминала. «&» Затем заставляет ваш скрипт перейти на задний план. В процессе производства вы, конечно, перенаправляете stdin / err в подходящий лог-файл.

Видеть

http://osdir.com/ml/network.openssh.general/2006-05/msg00017.html

Редактировать:

Только что выяснил, что < /dev/nullвыше не является необходимым (но перенаправление stdout / err есть ). Понятия не имею, почему ...

sleske
источник
Спасибо, это именно то, что я искал - мне не пришло в голову, что процесс унаследует std * даже при использовании & для запуска в фоновом режиме.
rmrobins
+1! Работает для меня. И вы также можете распечатать вывод, ssh user@host "/script/to/run > /tmp/ssh.stdout 2>&1 && cat /tmp/ssh.stdout && rm -f /tmp/ssh.stdout"
повторив
5

Вы можете попробовать nohup . Man nohup для более подробной информации.

ssh host "nohup script &"

Если вы хотите сохранить вывод на удаленном компьютере, вот вариант .

ssh user@host 'export REMOTE=myname; nice nohup ./my-restart >
logfile.log 2>&1 &'
Джодер Хо
источник
5

Другой альтернативой было бы запустить отдельный screen(1), что-то вроде:

ssh -l user host "screen -d -m mycommand"

Это запустит отдельный экран (который фиксирует все взаимодействия внутри него), а затем сразу же вернется, завершив сеанс ssh.

С немного большей изобретательностью вы можете решать довольно сложные удаленные вызовы команд таким образом.

towo
источник
4
 -f      Requests ssh to go to background just before command execution.
         This is useful if ssh is going to ask for passwords or
         passphrases, but the user wants it in the background.  This
         implies -n.  The recommended way to start X11 programs at a
         remote site is with something like ssh -f host xterm.

         If the ExitOnForwardFailure configuration option is set to “yes”,
         then a client started with -f will wait for all remote port for‐
         wards to be successfully established before placing itself in the
         background.
Тедди
источник
1
Проблема этого метода заключается в том, что команда SSH фактически не завершена, она просто скрыта в фоновом режиме, поэтому хост, на котором выполняется сценарий, будет иметь большое количество команд SSH в фоновом режиме, которые никогда не возвращаются, поскольку команды SSH никогда не возвращаются ( т.е. корневая проблема, которую я хочу решить)
rmrobins
-1

Я думаю, что правильный путь будет

ssh user@host exec script.sh &
Nik
источник
Нет, это не работает для меня. Зачем это?
слеске
Я не использовал фоновый пуш через ssh, пытался без термина под рукой. моя вина.
Ник