Получение SSH для выполнения команды в фоновом режиме на целевой машине - PullRequest
272 голосов
/ 27 августа 2008

Это дополнительный вопрос к Как вы используете ssh в сценарии оболочки? вопрос. Если я хочу выполнить команду на удаленной машине, которая работает в фоновом режиме на этой машине, как мне получить команду ssh для возврата? Когда я пытаюсь просто включить амперсанд (&) в конце команды, он просто зависает. Точная форма команды выглядит следующим образом:

ssh user@target "cd /some/directory; program-to-execute &"

Есть идеи? Следует отметить, что при входе на целевой компьютер всегда появляется текстовый баннер, и у меня настроены ключи SSH , поэтому пароль не требуется.

Ответы [ 14 ]

279 голосов
/ 27 августа 2008

У меня была эта проблема в программе, которую я написал год назад - оказывается, ответ довольно сложный. Вам нужно будет использовать nohup, а также перенаправление вывода, как объяснено в википедии artcle на nohup , скопированной здесь для вашего удобства.

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

nohup myprogram > foo.out 2> foo.err < /dev/null &
242 голосов
/ 14 мая 2010

Это был самый чистый способ сделать это для меня: -

ssh -n -f user@host "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"

После этого запускается только команда на удаленном компьютере

27 голосов
/ 17 марта 2012

перенаправить fd's

Вывод необходимо перенаправить с помощью &>/dev/null, который перенаправляет как stderr, так и stdout в / dev / null и является синонимом >/dev/null 2>/dev/null или >/dev/null 2>&1.

1008 * круглые скобки * Лучший способ - использовать sh -c '( ( command ) & )', где команда - это что угодно. ssh askapache 'sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"' Nohup Shell

Вы также можете использовать nohup напрямую для запуска оболочки:

ssh askapache 'nohup sh -c "( ( chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

Приятный старт

Еще одна хитрость заключается в использовании nice для запуска команды / оболочки:

ssh askapache 'nice -n 19 sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
18 голосов
/ 05 сентября 2012

Я просто хотел показать рабочий пример, который вы можете вырезать и вставить:

ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /dev/null &\""
17 голосов
/ 27 августа 2008

Если вы не можете / не можете держать соединение открытым, вы можете использовать screen , если у вас есть права на его установку.

user@localhost $ screen -t remote-command
user@localhost $ ssh user@target # now inside of a screen session
user@remotehost $ cd /some/directory; program-to-execute &

Чтобы отсоединить сеанс экрана: ctrl-a d

Чтобы отобразить сеансы экрана:

screen -ls

Чтобы присоединить сеанс:

screen -d -r remote-command

Обратите внимание, что экран также может создавать несколько оболочек в каждом сеансе. Подобный эффект может быть достигнут с tmux .

user@localhost $ tmux
user@localhost $ ssh user@target # now inside of a tmux session
user@remotehost $ cd /some/directory; program-to-execute &

Чтобы отсоединить сеанс tmux: ctrl-b d

Чтобы отобразить сеансы экрана:

tmux list-sessions

Чтобы снова подключить сеанс:

tmux attach <session number>

Клавиша управления tmux по умолчанию, ' ctrl-b ', довольно сложна в использовании, но есть несколько примеров конфигураций tmux, которые поставляются с tmux, которые вы можете попробовать.

9 голосов
/ 11 июля 2014

Самый быстрый и простой способ - использовать команду 'at':

ssh user @ target "сейчас -f /home/foo.sh"

6 голосов
/ 11 сентября 2008

Я думаю, вам придется объединить пару ответов, чтобы получить то, что вы хотите. Если вы используете nohup в сочетании с точкой с запятой и заключаете все это в кавычки, то вы получите:

ssh user@target "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"

, который, кажется, работает для меня. С nohup вам не нужно добавлять & к команде для запуска. Также, если вам не нужно читать какие-либо выходные данные команды, вы можете использовать

ssh user@target "cd /some/directory; nohup myprogram > /dev/null 2>&1"

чтобы перенаправить весь вывод в /dev/null.

5 голосов
/ 25 июля 2013

Это сработало для меня раз:

ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & " 
1 голос
/ 13 июня 2017

На самом деле, всякий раз, когда мне нужно выполнить команду на удаленной машине, которая является сложной, мне нравится помещать команду в скрипт на конечном компьютере, и просто запускать этот скрипт, используя ssh.

Например:

# simple_script.sh (located on remote server)

#!/bin/bash

cat /var/log/messages | grep <some value> | awk -F " " '{print $8}'

А потом я просто запускаю эту команду на исходном компьютере:

ssh user@ip "/path/to/simple_script.sh"
0 голосов
/ 20 мая 2019

Мне показалось довольно удобным иметь сеанс remote tmux с использованием синтаксиса tmux new -d <shell cmd>, подобного следующему:

ssh someone@elsewhere 'tmux new -d sleep 600'

Это запустит новый сеанс на elsewhere хосте, а команда ssh на локальном компьютере вернется к оболочке почти мгновенно. Затем вы можете подключиться по ssh к удаленному хосту и tmux attach к этому сеансу. Обратите внимание, что в локальном tmux нет ничего, кроме удаленного!

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

ssh someone@elsewhere 'tmux new -d "~/myscript.sh; bash"'
...