Fare in modo che ssh esegua un comando in background sul computer di destinazione

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

  •  09-06-2019
  •  | 
  •  

Domanda

Questa è una domanda successiva a Come si usa ssh in uno script di shell? domanda.Se voglio eseguire un comando sulla macchina remota che viene eseguito in background su quella macchina, come posso ottenere la restituzione del comando ssh?Quando provo a includere solo la e commerciale (&) alla fine del comando, si blocca.La forma esatta del comando è simile alla seguente:

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

Qualche idea?Una cosa da notare è che gli accessi al computer di destinazione producono sempre un banner di testo e io ho SSH tasti configurati in modo che non sia richiesta alcuna password.

È stato utile?

Soluzione

Ho avuto questo problema in un programma che ho scritto un anno fa: la risposta è piuttosto complicata.Dovrai utilizzare nohup e il reindirizzamento dell'output, come spiegato nell'articolo di Wikipedia su no, copiato qui per vostra comodità.

I lavori sfondi di nohuping sono ad esempio utili quando effettuato l'accesso tramite SSH, poiché i lavori di fondo possono far sì che il guscio si blocchi al logout a causa di una condizione di gara [2].Questo problema può anche essere superato reindirizzando tutti e tre i flussi I/O:

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

Altri suggerimenti

Questo è stato il modo più pulito per farlo per me: -

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

L'unica cosa che viene eseguita dopo è il comando effettivo sulla macchina remota

Reindirizzare gli fd

L'output deve essere reindirizzato con &>/dev/null che reindirizza sia stderr che stdout a /dev/null ed è un sinonimo di >/dev/null 2>/dev/null O >/dev/null 2>&1.

Parantesi

Il modo migliore è usare sh -c '( ( command ) & )' dove comando è qualsiasi cosa.

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

Nohup Shell

Puoi anche usare nohup direttamente per avviare la shell:

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

Bel lancio

Un altro trucco è usare nice per avviare il comando/shell:

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

Volevo solo mostrare un esempio funzionante che puoi tagliare e incollare:

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

Se non riesci/non riesci a mantenere aperta la connessione, potresti utilizzare schermo, se disponi dei diritti per installarlo.

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 &

Per scollegare la sessione dello schermo: ctrl-a D

Per elencare le sessioni dello schermo:

screen -ls

Per ricollegare una sessione:

screen -d -r remote-command

Tieni presente che lo schermo può anche creare più shell all'interno di ciascuna sessione.Un effetto simile può essere ottenuto con tmux.

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

Per scollegare la sessione tmux: ctrl-b D

Per elencare le sessioni dello schermo:

tmux list-sessions

Per ricollegare una sessione:

tmux attach <session number>

Il tasto di controllo tmux predefinito, 'ctrl-b', è piuttosto difficile da usare, ma ci sono diversi esempi di configurazioni tmux fornite con tmux che puoi provare.

Il modo più rapido e semplice è utilizzare il comando 'at':

ssh utente@destinazione "at now -f /home/foo.sh"

Penso che dovrai combinare un paio di queste risposte per ottenere ciò che desideri.Se usi nohup insieme al punto e virgola e racchiudi il tutto tra virgolette, otterrai:

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

che sembra funzionare per me.Con nohup, non è necessario aggiungere & al comando da eseguire.Inoltre, se non è necessario leggere l'output del comando, è possibile utilizzare

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

per reindirizzare tutto l'output su /dev/null.

Questo ha funzionato per me molte volte:

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

In realtà, ogni volta che ho bisogno di eseguire un comando complicato su una macchina remota, mi piace inserire il comando in uno script sulla macchina di destinazione ed eseguire semplicemente lo script utilizzando ssh.

Per esempio:

# simple_script.sh (located on remote server)

#!/bin/bash

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

E poi eseguo semplicemente questo comando sulla macchina di origine:

ssh user@ip "/path/to/simple_script.sh"

Stavo cercando di fare la stessa cosa, ma con la complessità aggiuntiva che stavo cercando di farlo da Java.Quindi su una macchina che esegue Java, stavo cercando di eseguire uno script su un'altra macchina, in background (con nohup).

Dalla riga di comando, ecco cosa ha funzionato:(potresti non aver bisogno del "-i keyFile" se non ti serve per ssh sull'host)

ssh -i keyFile user@host bash -c "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\""

Nota che nella mia riga di comando c'è un argomento dopo "-c", che è tutto tra virgolette.Ma affinché funzioni dall'altra parte, ha ancora bisogno delle virgolette, quindi ho dovuto inserirle delle virgolette sfuggite.

Da Java, ecco cosa ha funzionato:

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.

Ci sono voluti un po' di tentativi ed errori per farlo funzionare, ma ora sembra funzionare bene.

Puoi farlo così...

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

Mi è sembrato abbastanza conveniente avere un file a distanza sessione tmux utilizzando il file tmux new -d <shell cmd> sintassi come questa:

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

Questo avvierà la nuova sessione elsewhere Il comando host e ssh sul computer locale tornerà alla shell quasi istantaneamente.È quindi possibile accedere tramite ssh all'host remoto e tmux attach a quella sessione.Nota che non c'è nulla sull'esecuzione di tmux locale, solo remoto!

Inoltre, se vuoi che la tua sessione persista una volta terminato il lavoro, aggiungi semplicemente un launcher di shell dopo il tuo comando, ma non dimenticare di racchiudere tra virgolette:

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

Penso che questo sia ciò di cui hai bisogno:Per prima cosa devi installare sshpass sulla tua macchina.quindi puoi scrivere il tuo script:

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

Per prima cosa segui questa procedura:

Accedi su A come utente a e genera una coppia di chiavi di autenticazione.Non inserire una passphrase:

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

Ora usa ssh per creare una directory ~/.ssh come utente b su B.(La directory potrebbe già esistere, il che va bene):

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

Infine aggiungi la nuova chiave pubblica di a a b@B:.ssh/authorized_keys e inserisci la password di b un'ultima volta:

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

D'ora in poi puoi accedere a B come b da A come a senza password:

a@A:~> ssh b@B

allora funzionerà senza inserire una password

ssh b@B "cd /qualche/directory;programma da eseguire &"

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top