Ho già impostato un agente ssh e posso eseguire comandi su un server esterno nello script Bash facendo cose come:
ssh blah_server "ls; pwd;"
Ora, quello che mi piacerebbe davvero fare è eseguire molti lunghi comandi su un server esterno. Racchiudere tutte queste tra virgolette sarebbe abbastanza brutto, e preferirei evitare di sshing più volte solo per evitare questo.
Quindi, c'è un modo per farlo in una volta racchiuso tra parentesi o qualcosa del genere? Sto cercando qualcosa sulla falsariga di:
ssh blah_server (
ls some_folder;
./someaction.sh;
pwd;
)
Fondamentalmente, sarò felice con qualsiasi soluzione purché sia pulita.
Per chiarire, sto parlando di questo essere parte di un copione bash più ampio. Altre persone potrebbero aver bisogno di gestire la sceneggiatura, quindi mi piacerebbe tenerla pulita. Non voglio avere uno script di bash con una riga che assomiglia a:
ssh blah_server "ls some_folder; ./someaction.sh 'some params'; pwd; ./some_other_action 'other params';"
perché è estremamente brutto e difficile da leggere.
Che ne dici di un Bash Qui documento :
ssh otherhost << EOF
ls some_folder;
./someaction.sh 'some params'
pwd
./some_other_action 'other params'
EOF
Per evitare i problemi menzionati da @Globalz nei commenti, potresti essere in grado (a seconda di quello che stai facendo sul sito remoto) di sostituire la prima riga con
ssh otherhost /bin/bash << EOF
Nota che puoi sostituire le variabili nel documento Here, ma potresti dover gestire problemi di quotatura. Ad esempio, se si cita la "stringa limite" (ad esempio EOF
nel precedente), non è possibile eseguire sostituzioni variabili. Ma senza citare la stringa limite, le variabili sono sostituite. Ad esempio, se hai definito $NAME
sopra nello script di Shell, puoi farlo
ssh otherhost /bin/bash << EOF
touch "/tmp/${NAME}"
EOF
e creerebbe un file sulla destinazione otherhost
con il nome di qualsiasi cosa tu avessi assegnato a $NAME
. Sono valide anche altre regole sulla quotazione degli script Shell, ma sono troppo complicate per entrare qui.
Modifica il tuo script localmente, quindi collegalo a ssh, ad es.
cat commands-to-execute-remotely.sh | ssh blah_server
dove commands-to-execute-remotely.sh
sembra il tuo elenco sopra:
ls some_folder
./someaction.sh
pwd;
Vedo due modi:
Innanzitutto fai una presa di controllo come questa:
ssh -oControlMaster=yes -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip>
ed esegui i tuoi comandi
ssh -oControlMaster=no -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip> -t <yourcommand>
In questo modo è possibile scrivere un comando ssh senza riconnettersi effettivamente al server.
Il secondo sarebbe quello di generare dinamicamente lo script, scp
ing it e in esecuzione.
Questo può anche essere fatto come segue . Metti i tuoi comandi in uno script, chiamiamolo comandi-inc.sh
#!/bin/bash
ls some_folder
./someaction.sh
pwd
Salva il file
Ora eseguilo sul server remoto.
ssh [email protected] 'bash -s' < /path/to/commands-inc.sh
Mai fallito per me.
SSH ed eseguire comandi multipli in Bash.
Separa i comandi con il punto e virgola in una stringa, passati a echo, tutti inviati al comando ssh. Per esempio:
echo "df -k;uname -a" | ssh 192.168.79.134
Pseudo-terminal will not be allocated because stdin is not a terminal.
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 18274628 2546476 14799848 15% /
tmpfs 183620 72 183548 1% /dev/shm
/dev/sda1 297485 39074 243051 14% /boot
Linux newserv 2.6.32-431.el6.x86_64 #1 SMP Sun Nov 10 22:19:54 EST 2013 x86_64 x86_64 x86_64 GNU/Linux
Metti tutti i comandi su uno script e può essere eseguito come
ssh <remote-user>@<remote-Host> "bash -s" <./remote-commands.sh
Per chiunque sia inciampato qui come me, ho avuto successo con la fuga dal punto e virgola e dalla nuova riga:
Primo passo: il punto e virgola. In questo modo, non interrompiamo il comando ssh:
ssh <Host> echo test\;ls
^ backslash!
Elenco degli host/home directory remoti (registrati come root), mentre
ssh <Host> echo test;ls
^ NO backslash
elencato la directory di lavoro corrente.
Prossimo passo: rompere la linea:
v another backslash!
ssh <Host> echo test\;\
ls
Questo ha di nuovo elencato la directory di lavoro remota - migliorata la formattazione:
ssh <Host>\
echo test\;\
ls
Se è molto più bello di qui documento o citazioni su linee spezzate - beh, non sono io a decidere ...
(Utilizzo di bash, Ubuntu 14.04 LTS.)
Questo funziona bene per la creazione di script, dato che non devi includere altri file:
#!/bin/bash
ssh <my_user>@<my_Host> "bash -s" << EOF
# here you just type all your commmands, as you can see, i.e.
touch /tmp/test1;
touch /tmp/test2;
touch /tmp/test3;
EOF
Il modo più semplice per configurare il sistema in modo che utilizzi sessioni Ssh singole per impostazione predefinita con multiplexing.
Questo può essere fatto creando una cartella per i socket:
mkdir ~/.ssh/controlmasters
E quindi aggiungendo quanto segue alla tua configurazione .ssh:
Host *
ControlMaster auto
ControlPath ~/.ssh/controlmasters/%[email protected]%h:%p.socket
ControlMaster auto
ControlPersist 10m
Ora, non è necessario modificare alcun codice. Ciò consente di effettuare più chiamate a ssh e scp senza creare più sessioni, il che è utile quando è necessaria una maggiore interazione tra le macchine locali e remote.
Grazie alla risposta di @ terminus, http://www.cyberciti.biz/faq/linux-unix-osx-bsd-ssh-multiplexing-to-speed-up-ssh-connections/ e https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing .
Le risposte postate usando stringhe multilinea e più script di bash non hanno funzionato per me.
Ecco un modo funzionale per ssh ed eseguire più comandi mantenendo il contesto locale.
LOCAL_VARIABLE=test
run_remote() {
echo "$LOCAL_VARIABLE"
ls some_folder;
./someaction.sh 'some params'
./some_other_action 'other params'
}
ssh otherhost "$(set); run_remote"
Non sono sicuro se il più pulito per comandi lunghi ma sicuramente il più semplice:
ssh [email protected] "cmd1; cmd2; cmd;3"