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

StackOverflow https://stackoverflow.com/questions/29142

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

Перенаправление 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 напрямую для запуска оболочки:

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 ) & )"'

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

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

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

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-а д

Чтобы просмотреть сеансы экрана:

screen -ls

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

screen -d -r remote-command

Обратите внимание, что screen также может создавать несколько оболочек в каждом сеансе.Аналогичного эффекта можно добиться с помощью 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 д

Чтобы просмотреть сеансы экрана:

tmux list-sessions

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

tmux attach <session number>

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

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

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

Я думаю, вам придется объединить пару этих ответов, чтобы получить то, что вы хотите.Если вы используете 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.

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

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

На самом деле, всякий раз, когда мне нужно запустить сложную команду на удаленном компьютере, я предпочитаю помещать команду в сценарий на целевой машине и просто запускать этот сценарий с помощью 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"

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

Из командной строки вот что сработало:(вам может не понадобиться «-i keyFile», если он вам не нужен для подключения к хосту по SSH)

ssh -i keyFile user@host 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.

Чтобы заставить это работать, потребовалось немного проб и ошибок, но теперь, похоже, все работает хорошо.

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

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

Мне показалось весьма удобным иметь удаленный сеанс 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"'

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

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

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

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

a@A:~> 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 a@A

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

a@A:~> ssh b@B mkdir -p .ssh
b@B's password: 

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

a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
b@B's password: 

С этого момента вы можете войти в систему B как b из A как a без пароля:

a@A:~> ssh b@B

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

ssh b@B "cd /some/directory;программа для выполнения &"

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top