Получение ssh для выполнения команды в фоновом режиме на целевой машине

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

ssh [email protected] "cd /some/directory; program-to-execute &"

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

Ответ 1

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

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

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

Ответ 2

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

ssh -n -f [email protected] "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"

Единственное, что работает после этого, - это фактическая команда на удаленном компьютере

Ответ 3

Перенаправить fd

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

круглые скобки

Лучший способ - использовать sh -c '( ( command ) & )', где команда - это что угодно.

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

Оболочка Nohup

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

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

Nice Launch

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

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

Ответ 4

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

[email protected] $ screen -t remote-command
[email protected] $ ssh [email protected] # now inside of a screen session
[email protected] $ cd /some/directory; program-to-execute &

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

Чтобы перечислить сеансы экрана:

screen -ls

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

screen -d -r remote-command

Обратите внимание, что экран также может создавать несколько оболочек в каждом сеансе. Подобного эффекта можно добиться с помощью tmux.

[email protected] $ tmux
[email protected] $ ssh [email protected] # now inside of a tmux session
[email protected] $ cd /some/directory; program-to-execute &

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

Чтобы перечислить сеансы экрана:

tmux list-sessions

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

tmux attach <session number>

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

Ответ 5

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

ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /dev/null &\""

Ответ 6

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

ssh user @target "на данный момент -f/home/foo.sh"

Ответ 7

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

ssh [email protected] "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"

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

ssh [email protected] "cd /some/directory; nohup myprogram > /dev/null 2>&1"

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

Ответ 8

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

ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & " 

Ответ 9

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

Например:

# simple_script.sh (located on remote server)

#!/bin/bash

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

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

ssh [email protected] "/path/to/simple_script.sh"

Ответ 10

Я пытался сделать то же самое, но с добавленной сложностью, которую я пытался сделать с Java. Поэтому на одной машине, на которой запущена java, я пытался запустить script на другой машине, в фоновом режиме (без nohup).

В командной строке вот что сработало: (вам может не понадобиться "-i keyFile", если вам не нужно ssh на хост)

ssh -i keyFile [email protected] bash -c "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\""

Обратите внимание, что в моей командной строке есть один аргумент после "-c", который находится в кавычках. Но для того, чтобы он работал на другом конце, он все еще нуждается в кавычках, поэтому мне пришлось помещать в него скрытые кавычки.

Из java, вот что сработало:

ProcessBuilder b = new ProcessBuilder("ssh", "-i", "keyFile", "bash", "-c",
 "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\"");
Process process = b.start();
// then read from process.getInputStream() and close it.

Для этой работы потребовалось немного проб и ошибок, но теперь это хорошо работает.

Ответ 11

Вы можете сделать это так...

sudo /home/script.sh -opt1 > /tmp/script.out &

Ответ 12

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

ssh [email protected] 'tmux new -d sleep 600'

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

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

ssh [email protected] 'tmux new -d "~/myscript.sh; bash"'

Ответ 13

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

ssh -l myaccount yourhost '~/myscript.sh' 2> & 1 &

Приглашение немедленно возвращается, сценарий по-прежнему возвращает вывод обратно к вам. Конечно, вы можете указать std * в null:

ssh -l myaccount yourhost '~/myscript.sh' 2> & 1 1>/dev/null </dev/null &

(Linux новичок здесь. Я не знаю никаких минусов. Будьте язычниками.)

Ответ 14

Я думаю, что это то, что вам нужно: Сначала вам нужно установить sshpass на свой компьютер. то вы можете написать свой собственный script:

while read pass port user ip; do
sshpass -p$pass ssh -p $port [email protected]$ip <<ENDSSH1
    COMMAND 1
    .
    .
    .
    COMMAND n
ENDSSH1
done <<____HERE
    PASS    PORT    USER    IP
      .      .       .       .
      .      .       .       .
      .      .       .       .
    PASS    PORT    USER    IP    
____HERE

Ответ 15

Сначала выполните следующую процедуру:

Войдите в систему как пользователь a и создайте пару ключей аутентификации. Не вводите ключевую фразу:

[email protected]:~> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/a/.ssh/id_rsa): 
Created directory '/home/a/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/a/.ssh/id_rsa.
Your public key has been saved in /home/a/.ssh/id_rsa.pub.
The key fingerprint is:
3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 [email protected]

Теперь используйте ssh для создания каталога ~/.ssh как пользователя b на B. (Возможно, каталог уже существует, и это нормально):

[email protected]:~> ssh [email protected] mkdir -p .ssh
[email protected] password: 

Наконец добавьте новый открытый ключ в b @B:.ssh/authorized_keys и введите пароль b в последний раз:

[email protected]:~> cat .ssh/id_rsa.pub | ssh [email protected] 'cat >> .ssh/authorized_keys'
[email protected] password: 

Теперь вы можете войти в B как b из A как без пароля:

[email protected]:~> ssh [email protected]

тогда это будет работать без ввода пароля

ssh b @B "cd/some/directory; program-to-execute &"