Con ssh, come è possibile eseguire un comando sul computer remoto senza uscire?


29

Normalmente, se si passa un comando a ssh in questo modo

ssh me@example.com 'some-command.sh'

Si ottiene una sessione non interattiva e ssh esce non appena viene eseguito il comando (o lo script o qualunque altra cosa). Come posso ottenere una sessione interattiva e tuttavia eseguire un comando che ho specificato dal mio computer locale. Ad esempio, vorrei poter aprire lo schermo e riavviare una sessione dello schermo specifica:

ssh me@example.com 'screen -r 12345'

ma ciò non è consentito, restituendo l'errore "Deve essere collegato a un terminale". che presumo significhi essenzialmente "deve chiamare questo comando da una shell interattiva".

Come altro esempio, uso un sacco di macchine al lavoro che spesso mi richiedono di utilizzare un account condiviso per avere i diritti di fare determinate cose (sì, lo so: cattiva idea ma non incolparmi, non ho impostato le cose che modo), e di solito hanno ksh come shell predefinita. Vorrei accedere, passare a bash (o zsh) e creare il .bash_profile del mio account (o .zshrc). Questo sarebbe facile se potessi stabilire una sessione ssh interattiva e passare un comando al computer remoto per eseguirlo all'accesso.

Ho in mente una soluzione kludgey (e non testata) che pubblicherò, ma spero che qualcuno conosca un modo migliore.

AGGIORNAMENTO: per coloro che non se ne sono resi conto, non ho intenzione di fare tutto questo a mano, quindi dirmi di aprire una sessione interattiva e poi farlo a mano in realtà non risolve nulla.

2 ° AGGIORNAMENTO: Per tentare ancora una volta di chiarire: sto cercando di eseguire comandi (arbitrari) sul server (specificati a livello di codice sul client) ma poi ho una sessione interattiva aperta che è influenzata da tutto ciò che viene fatto da quei comandi programmatici.


echo "command" | ssh user@remote_host
laggingreflex,

2
Ti sei perso la parte "senza uscire" della domanda? Sono abbastanza sicuro che questo uscirà al termine del comando.
iconoclasta il

Risposte:


26

Puoi provare il seguente comando per avviare bash e creare il tuo profilo quando ssh:

ssh  -t hostname "bash --rcfile ~user/.bashrc"

4
+1. L' -tinterruttore risolve anche il problema dell'interrogatore screen.
Patch

3
Può essere usato con comandi arbitrari, senza chiudere la connessione? Se provo ssh -t www.dev "echo 'hi there'", la connessione viene immediatamente chiusa dopo l'esecuzione del comando.
iconoclasta il

11

Sulla base della risposta di dogbane, una soluzione completa è simile a:

ssh -t user@server 'cd /a/great/place; bash'

Qui uso -tper forzare l'allocazione di uno pseudo-terminale, necessario per una shell interattiva. Quindi eseguo due comandi sul server: prima cosa che volevo fare prima di aprire la shell interattiva (nel mio caso, cambiare directory in una cartella specifica), e poi la shell interattiva stessa. bash vede che ha uno pseudo-terminale e risponde in modo interattivo.

Le virgolette singole assicurano che l'intera cosa venga passata al server remoto come comando da eseguire dalla shell predefinita.

Grazie ancora a dogbane per averci fornito gli indizi necessari -t. Ero solito risolvere questo problema expect, che sta sicuramente uccidendo un topo con un cannone. (:


2

Prova questa soluzione.

echo "command" | ssh user@remote_host

L'accesso è interattivo e il comando viene passato come se fosse stato digitato sulla riga di comando interattiva. La sessione termina come se fosse stata digitata

ssh user@remote_host 'command'

3
Se la sessione termina al termine del comando, questo non risponde alla domanda. L'intero punto del comando deve essere lasciato con una sessione interattiva dopo l'esecuzione del comando, non semplicemente per inviare comandi ai server ssh.
iconoclasta il

Questo è utile almeno per simulare un'interazione per l'esecuzione del comando, senza usare -to il proprio file bash. +1
laggingreflex,

0

Usa ssh -X per usare termIO cmds.

Inoltre, puoi concatenare i tuoi cmd come "ssh 'source ~ / .bashrc && cd && do'"


ma dopo che l'intera catena è terminata, non ho più una sessione interattiva, giusto? Si chiude ancora, vero?
iconoclasta

E ti interesserebbe approfondire la soluzione termIO?
iconoclasta

0

perché non installare staccare sul sistema remoto e usare:

ssh -t user@example.com "/home/user/bin/detach ls"

questo funzionerà 'ls' e POI mi lascerà con una sessione interattiva? Che cosa succede se, anziché "ls", eseguo "source .somefile" per ottenere alcuni alias e funzioni. Saranno disponibili nella mia sessione interattiva o saranno stati eseguiti in una sessione diversa?
iconoclasta il

No, a causa di detach, lsnon mantiene aperta la sessione e si disconnetterà senza stampare l'output di lsma continuerà comunque.
Dan D. il

Sto cercando di eseguire comandi (arbitrari) sul server (specificati a livello di codice sul client) ma poi ho una sessione interattiva aperta che è influenzata da qualsiasi cosa fatta da quei comandi programmatici. Quindi, se ti capisco correttamente, questo non mi aiuta.
iconoclasta il

0

La risposta di laggingreflex è vicina ... La cambierei come segue:

echo "command\n$(cat -)" | ssh user@remote_host

Sfortunatamente, non ti piacerà il modo in cui funziona, perché "cat" bufferizza le righe che scrive su stdout ... Se creiamo uno script chiamato "echo-cat" che assomiglia a questo:

{
  echo "${@}"
 #cat buffers & won't flush to stdout immediately
 #cat -
  IFS='\n'
  while read line
  do
        echo "${line}"
  done
}

otterremo lo stesso risultato senza il buffering:

echo-cat "command" | ssh user@remote_host

Questo probabilmente ti porterà molto più vicino al tuo obiettivo ...


0

Questo è kludgey e non testato, ma penso che dovrebbe funzionare.

Crea uno script chiamato (ad esempio) remote-starter che accetta un argomento tra virgolette dopo un argomento user @ host:

remote-starter user@example.com 'some-command.sh arg1 arg2'

Questo script dovrebbe prima salvare il comando tra virgolette (senza virgolette) nel file denominato (ad es.) .onetimeSul computer remoto, quindi eseguire un normale comando ssh, questa volta senza passare alcun comando da eseguire sul computer remoto. (Se si esegue ssh user@example.com all'interno di uno script, potrebbe funzionare per eseguire exec ssh user@example.com.)

Affinché ciò funzioni, la macchina remota deve .onetimeprovenire dal proprio .bash_profile o .zshrc o altro. Dopo l'esecuzione .onetime, dovrebbe essere eliminato .onetime, quindi il file non verrà eseguito al successivo accesso regolare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.