it-swarm.com.de

Eine Remote-SSH-Sitzung "speichern"?

Ich versuche dies in einem Skript zu tun. Ich muss einige Befehle auf einem Remote-Host ausführen. Derzeit mache ich das:

ssh [email protected] 'bash -s' < command1
ssh [email protected] 'bash -s' < command2
ssh [email protected] 'bash -s' < command3

Dies bedeutet jedoch, dass ich wiederholt eine Verbindung zum Server herstellen muss, was die Zeit zwischen der Verarbeitung der Befehle erheblich verlängert. Ich suche so etwas:

varSession=$(ssh [email protected] 'bash -s')
varSeesion < command1
varSeesion < command2
varSeesion < command3

Auch hier muss ich diese Befehle über ein Skript ausführen. Ich habe mir screen angesehen, bin mir aber nicht sicher, ob es in einem Skript verwendet werden kann.

12
SayantanRC

Sie können ControlMaster und ControlPersist verwenden, damit eine Verbindung nach Beendigung des Befehls bestehen bleibt:

Gibt in Verbindung mit ControlMaster an, dass die Master-Verbindung im Hintergrund geöffnet bleiben soll (auf zukünftige Client-Verbindungen warten), nachdem die erste Client-Verbindung geschlossen wurde. Wenn no festgelegt ist, wird die Master-Verbindung nicht in den Hintergrund gestellt und geschlossen, sobald die anfängliche Client-Verbindung geschlossen wird. Bei der Einstellung yes oder 0 Bleibt die Master-Verbindung unbegrenzt im Hintergrund (bis sie über einen Mechanismus wie „ssh -O exit“ Beendet oder geschlossen wird). Wenn eine Zeit in Sekunden oder eine Zeit in einem der in sshd_config(5) dokumentierten Formate festgelegt ist, wird die Hintergrund-Master-Verbindung automatisch beendet, nachdem sie für die angegebene Zeit inaktiv war (ohne Client-Verbindungen).

Der erste SSH-Befehl richtet also eine Steuerdatei für die Verbindung ein, und die beiden anderen verwenden diese Verbindung über diese Steuerdatei wieder. Ihr ~/.ssh/config Sollte ungefähr Folgendes haben:

Host host
    User root
    ControlMaster auto
    ControlPath /tmp/ssh-control-%C
    ControlPersist 30   # or some safe timeout

Und Ihr Skript benötigt keine weiteren Änderungen.

29
muru

Sie könnten einen Hinweis von einem ähnliche Frage auf StackOverflow nehmen und eine Bash verwenden. Hier Dokument :

ssh [email protected] 'bash -s' << EOF
  command1
  command2
  command3
EOF
7
Twinkles

Sie können das Skript expect verwenden. Es kann die SSH-Verbindung automatisieren und Befehle auf dem Remote-Computer ausführen. Dieser Code sollte etwas Licht in die Automatisierung der SSH-Verbindung bringen.

sie suchen so etwas. Speichern Sie den folgenden Code in einer Datei foo.expect

#login to the remote machine
spawn ssh [email protected]
expect "?assword" { send "yourpassword\r"}

#execute the required commands; following demonstration uses echo command
expect "$ " {send "echo The falcon has landed\r"}
expect "$ " {send "echo The falcons have landed\r"}
expect "$ " {send "echo Will the BFR? land? \r"}

#exit from the remote machine
expect "$ " {send "exit\r"}

führen Sie es als expect foo.expect

Sie müssen erwarten, dass die Anwendung dieses Skript ausführt. Es kann mit dem Befehl apt-get install expect Installiert werden.

Dieses Buch hilft Ihnen dabei, das erwartete Skript zu erkunden. Viel Spaß beim Scripting!

4
daedalus_hamlet

Unabhängiger Dateideskriptor für einen oder mehrere [~ # ~] ssh [~ # ~] Verbindungen

Ich zusätzlich zu ControlPath und ControlPersist korrekter Weg, vorgeschlagen von Murus Antwort , ich möchte eine Alternative vorstellen:

Methode

  1. Erstellen Sie ein Fifo, das Sie für die Ausgaben von ssh verwenden

    Sie müssen diese Datei in einem Pfad erstellen, von dem Sie sicher sind

    mkfifo $HOME/sshfifo
    
  2. Führen Sie den Befehl aus :

    exec 8> >(exec ssh [email protected] /bin/bash >$HOME/sshfifo
    exec 9<$HOME/sshfifo
    
  3. Dann brauchst du jetzt das Fifo nicht mehr

    rm $HOME/sshfifo
    
  4. Sie können jetzt Befehle von Ihrer Verbindung senden und empfangen:

    echo >&8 uptime
    while read -t .002 -r -u 9 answer;do echo "$answer";done
    

    Hinweis: 0.002 seconds Ist bei schlechten Internetverbindungen möglicherweise nicht ausreichend. Das Zeitlimit kann je nach Art der Anforderungen unbrauchbar sein. Dies könnte überhaupt angepasst werden, um welche Art von Dialog es sich handelt.

    Und so weiter...

    myremote() {
        echo "[email protected]" >&8
        while IFS= read -t .02 -r -u 9 answer;do
             echo "$answer"
        done
    }
    
  5. Dies bleibt so lange bestehen, bis Sie diese Verbindung explizit schließen:

    exec 8>&-
    exec 9<&-
    

Des Weiteren

Das ist nicht perfekt. Du könntest

  • Binden Sie [~ # ~] stderr [~ # ~] ebenfalls mit einem zweiten Fifo

    mkfifo $HOME/sshfifo{out,err}
    exec 8> >(exec ssh [email protected] /bin/bash >$HOME/sshfifoout 2>$HOME/sshfifoerr)
    exec 9<$HOME/sshfifoout
    exec 10<$HOME/sshfifoerr
    rm $HOME/sshfifo{out,err}
    
  • Verwenden Sie interaktive Bash und reduzieren Sie das Timeout

    mkfifo $HOME/sshfifo{out,err}
    exec 8> >(exec ssh -tT [email protected] /bin/bash -i >$HOME/sshfifoout 2>$HOME/sshfifoerr)
    exec 9<$HOME/sshfifoout
    exec 10<$HOME/sshfifoerr
    rm $HOME/sshfifo{out,err}
    echo >&8 'set -i;PS1="ReAdY aS BoUnD\\n"'
    while IFS= read -d '' -rn 1 -t .02 -u 9 foo;do echo -n "$foo";done
    while IFS= read -d '' -rn 1 -t .02 -u 10 foo;do echo -n "$foo";done
    

    ... wenn Sie dann von /^ReAdY aS BoUnD$/ nach fd/10 als Markierung für Ende der Ausführung des letzten Befehls suchen, können Sie dies vermeiden Zeitüberschreitung für STDERR (-u 10), dann Zeitüberschreitung für STDOUT (-u 9 -t .002) reduzieren.

Und von dort

Es ist sogar möglich, mehrere Verbindungen zu öffnen, um sie zusammen zu verwenden

mkfifo $HOME/sshfifo
exec 8> >(exec ssh [email protected] /bin/bash >$HOME/sshfifo 2>&1)
exec 9<$HOME/sshfifo
rm $HOME/sshfifo

mkfifo $HOME/sshfifo
exec 11> >(exec ssh [email protected] /bin/bash >$HOME/sshfifo 2>&1)
exec 12<$HOME/sshfifo
rm $HOME/sshfifo

Dann

tee <<<uptime /dev/fd/8 >&11
read -u  9 -t .02 ansA
read -u 12 -t .02 ansB

denselben Befehl gleichzeitig an beide Enden senden ...

2
F. Hauri

Sie können cat verwenden, um alle Dateien zu verketten und sie dann an ssh weiterzuleiten.

cat command1 command2 command3 | ssh [email protected] 'bash -s'
1
Barmar