Ich habe bereits einen SSH-Agenten eingerichtet und kann Befehle auf einem externen Server in einem Bash-Skript ausführen.
ssh blah_server "ls; pwd;"
Nun möchte ich wirklich sehr lange Befehle auf einem externen Server ausführen. Alle diese Anführungszeichen in Anführungszeichen zu setzen, wäre ziemlich hässlich, und ich möchte lieber mehrmals ssh'ing machen, um dies zu vermeiden.
Gibt es eine Möglichkeit, dies auf einmal zu tun, eingeschlossen in Klammern oder etwas? Ich suche etwas in der Art von:
ssh blah_server (
ls some_folder;
./someaction.sh;
pwd;
)
Grundsätzlich bin ich mit jeder Lösung zufrieden, solange sie sauber ist.
Um dies zu verdeutlichen, spreche ich davon, dass dies Teil eines größeren Bash-Skripts ist. Andere Leute müssen sich möglicherweise mit dem Skript befassen, also möchte ich es sauber halten. Ich möchte kein Bash-Skript mit einer Zeile haben, die wie folgt aussieht:
ssh blah_server "ls some_folder; ./someaction.sh 'some params'; pwd; ./some_other_action 'other params';"
weil es extrem hässlich und schwer zu lesen ist.
Wie wäre es mit einem Bash Here Document :
ssh otherhost << EOF
ls some_folder;
./someaction.sh 'some params'
pwd
./some_other_action 'other params'
EOF
Um die von @Globalz in den Kommentaren genannten Probleme zu vermeiden, können Sie (je nachdem, was Sie auf der Remote-Site tun) die erste Zeile durch ersetzen
ssh otherhost /bin/bash << EOF
Beachten Sie, dass Sie im Here-Dokument eine Variablensubstitution durchführen können, dass Sie sich jedoch möglicherweise mit Zitierungsproblemen befassen müssen. Wenn Sie beispielsweise die "Begrenzungszeichenfolge" (z. B. EOF
oben) angeben, können Sie keine Variablenersetzungen durchführen. Ohne die Begrenzungszeichenfolge anzugeben, werden die Variablen jedoch ersetzt. Wenn Sie beispielsweise $NAME
oben in Ihrem Shell-Skript definiert haben, können Sie dies tun
ssh otherhost /bin/bash << EOF
touch "/tmp/${NAME}"
EOF
und es würde eine Datei auf dem Ziel otherhost
mit dem Namen dessen erstellen, was Sie $NAME
zugewiesen haben. Es gelten auch andere Regeln für das Zitieren von Shell-Skripten, die jedoch zu kompliziert sind.
Bearbeiten Sie Ihr Skript lokal und leiten Sie es in ssh weiter, z.
cat commands-to-execute-remotely.sh | ssh blah_server
wo commands-to-execute-remotely.sh
wie oben in deiner Liste aussieht:
ls some_folder
./someaction.sh
pwd;
Um Ihrem Beispielcode zu entsprechen, können Sie Ihre Befehle in einfache oder doppelte Anführungszeichen setzen. Zum Beispiel
ssh blah_server "
ls
pwd
"
Ich sehe zwei Möglichkeiten:
Zuerst machen Sie eine Kontrollbuchse wie folgt:
ssh -oControlMaster=yes -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip>
und führen Sie Ihre Befehle aus
ssh -oControlMaster=no -oControlPath=~/.ssh/ssh-%r-%h-%p <yourip> -t <yourcommand>
Auf diese Weise können Sie einen ssh-Befehl schreiben, ohne sich tatsächlich mit dem Server zu verbinden.
Die zweite wäre, das Skript dynamisch zu generieren, scp
ing und auszuführen.
Dies kann auch wie folgt durchgeführt werden: Geben Sie Ihre Befehle in ein Skript ein, nennen wir es befehle-inc.sh
#!/bin/bash
ls some_folder
./someaction.sh
pwd
Speicher die Datei
Führen Sie es jetzt auf dem Remote-Server aus.
ssh [email protected] 'bash -s' < /path/to/commands-inc.sh
Nie für mich gescheitert.
SSH und mehrere Befehle in Bash ausführen.
Separate Befehle mit Semikolons innerhalb eines Strings, die an echo übergeben werden, alle an den Befehl ssh weitergeleitet. Zum Beispiel:
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
Setzen Sie alle Befehle in ein Skript und es kann wie ausgeführt werden
ssh <remote-user>@<remote-Host> "bash -s" <./remote-commands.sh
Für jeden, der hier wie ich stolpert - ich hatte Erfolg damit, dem Semikolon und dem Newline zu entgehen:
Erster Schritt: das Semikolon. Auf diese Weise unterbrechen wir den Befehl ssh nicht:
ssh <Host> echo test\;ls
^ backslash!
Das entfernte Verzeichnis hosts/home (als root angemeldet) wurde aufgelistet
ssh <Host> echo test;ls
^ NO backslash
das aktuelle Arbeitsverzeichnis aufgelistet.
Nächster Schritt: Aufbrechen der Linie:
v another backslash!
ssh <Host> echo test\;\
ls
Hier wurde erneut das Remote-Arbeitsverzeichnis aufgelistet - verbesserte Formatierung:
ssh <Host>\
echo test\;\
ls
Ob wirklich schöner als hier Dokument oder Zitate um gebrochene Linien - na gut, ich entscheide nicht ...
(Mit bash, Ubuntu 14.04 LTS.)
Dies eignet sich gut zum Erstellen von Skripts, da Sie keine anderen Dateien hinzufügen müssen:
#!/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
Der einfachste Weg, um Ihr System für die Verwendung einzelner SSH-Sitzungen standardmäßig mit Multiplexing zu konfigurieren.
Dazu können Sie einen Ordner für die Sockel erstellen:
mkdir ~/.ssh/controlmasters
Fügen Sie dann der .ssh-Konfiguration Folgendes hinzu:
Host *
ControlMaster auto
ControlPath ~/.ssh/controlmasters/%[email protected]%h:%p.socket
ControlMaster auto
ControlPersist 10m
Jetzt müssen Sie keinen Code ändern. Dies ermöglicht mehrere Aufrufe von ssh und scp, ohne dass mehrere Sitzungen erstellt werden müssen. Dies ist nützlich, wenn mehr Interaktion zwischen Ihren lokalen und Remote-Computern erforderlich ist.
Dank der Antwort von @ terminus http://www.cyberciti.biz/faq/linux-unix-osx-bsd-ssh-multiplexing-to-speed-up-ssh-connections/ und https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing .
Die geposteten Antworten mit mehrzeiligen Zeichenfolgen und mehreren Bash-Skripts funktionierten für mich nicht.
Hier ist ein funktionaler Weg, um ssh auszuführen und mehrere Befehle auszuführen, während der lokale Kontext beibehalten wird.
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"
Nicht sicher, ob das sauberste für lange Befehle ist, aber sicherlich das einfachste
ssh [email protected] "cmd1; cmd2; cmd;3"