запуск удаленного скрипта через ssh, содержащий nohup - PullRequest
7 голосов
/ 06 ноября 2010

Я хочу запустить скрипт удаленно через ssh так:

ssh user@remote.org -t 'cd my/dir && ./myscript data my@email.com'

Скрипт выполняет различные действия, которые работают нормально, пока не доходит до строки с nohup:

nohup time ./myprog $1 >my.log && mutt -a ${1%.*}/`basename $1` -a ${1%.*}/`basename ${1%.*}`.plt $2 < my.log 2>&1 &

предполагается, что он запустит программу myprog, направит ее вывод в mylog и отправит электронное письмо с некоторыми файлами данных, созданными myprog в качестве вложения, и журналом в виде тела. Хотя, когда скрипт достигает этой строки, ssh выдает:

Соединение с remote.org закрыто.

В чем здесь проблема?

Спасибо за любую помощь

Ответы [ 3 ]

6 голосов
/ 13 декабря 2010

Ваша команда запускает конвейер процессов в фоновом режиме, поэтому вызывающий скрипт сразу же завершится (или очень скоро после этого).Это заставит ssh закрыть соединение.Это, в свою очередь, приведет к отправке SIGHUP любому процессу, подключенному к терминалу, для которого была создана опция -t.

Ваш time ./myprog процесс защищен nohup, поэтомуон должен продолжать бежать.Но ваш mutt нет, и это, вероятно, проблема здесь.Я предлагаю вам изменить вашу командную строку на:

nohup sh -c "time ./myprog $1 >my.log && mutt -a ${1%.*}/`basename $1` -a ${1%.*}/`basename ${1%.*}`.plt $2 < my.log 2>&1 " &

, чтобы весь конвейер был защищен.(Если это не помогает, может потребоваться что-то сделать с файловыми дескрипторами - например, у mutt могут возникнуть другие проблемы с отсутствующим терминалом - или же может потребоваться настройка в зависимости от параметров - но попробуйтесейчас ...)

5 голосов
/ 28 октября 2012

Этот ответ может быть полезным. Таким образом, чтобы достичь желаемого эффекта, вы должны сделать следующие вещи:

  1. Перенаправить все операции ввода-вывода по команде удаленного nohup'ed
  2. Скажите вашей локальной SSH-команде выйти, как только она закончит запуск удаленного процесса (-ов).

Цитируя ответ, который я уже упоминал , в свою очередь цитируя wikipedia :

Nohuping фоновые задания, например, полезны при входе через SSH, так как фоновые задания могут привести к зависанию оболочки при выходе из-за состояния гонки [2]. Эту проблему также можно решить путем перенаправления всех трех потоков ввода-вывода:

nohup myprogram > foo.out 2> foo.err < /dev/null &

UPDATE

Я только что имел успех с этим шаблоном:

ssh -f user@host 'sh -c "( (nohup command-to-nohup 2>&1 >output.file </dev/null) & )"'
0 голосов
/ 21 июня 2018

Мне удалось решить эту проблему для случая использования, когда мне нужно запускать фоновые скрипты удаленно через ssh, используя технику, аналогичную другим ответам здесь, но в некотором смысле я чувствую себя более простым и чистым (по крайней мере, это делает мой код корочеи - я считаю - более привлекательным), явно закрывая все три потока, используя синтаксис перенаправления закрытия потока (как обсуждалось в следующих местах:

  1. https://unix.stackexchange.com/questions/131801/closing-a-file-descriptor-vs

  2. https://unix.stackexchange.com/questions/70963/difference-between-2-2-dev-null-dev-null-and-dev-null-21

  3. http://www.tldp.org/LDP/abs/html/io-redirection.html#CFD

  4. https://www.gnu.org/software/bash/manual/html_node/Redirections.html

Скорее, чем более широко используемые, но(IMHO) хакер "перенаправить в / из / dev / null", в результате чего обманчиво просто:

    nohup script.sh >&- 2>&- <&-&

2>&1 работает так же хорошо, как 2> & -, но я чувствую, что последнее всегда-по-чуть более понятно.;) У большинства людей может быть пробел, предшествующий конечному амперсанду "фоновой работы", но поскольку он не требуется (так как сам амперсанд функционирует как точка с запятой при обычном использовании), я предпочитаю его опускать.:)

...