it-swarm.com.de

Wie verwende ich SSH, um ein Shell-Skript auf einem Remotecomputer auszuführen?

Ich muss ein Shell-Skript (Windows/Linux) auf einem Remotecomputer ausführen.

Ich habe SSH auf Computer A und B konfiguriert. Mein Skript befindet sich auf Computer A, auf dem ein Teil meines Codes auf einem Remote-Computer, Computer B, ausgeführt wird.

Die lokalen und Remote-Computer können Windows- oder Unix-basierte Systeme sein.

Gibt es eine Möglichkeit, dies mit plink/ssh auszuführen?

1136
Arun

Wenn Maschine A eine Windows-Box ist, können Sie Plink (Teil von PuTTY ) mit dem Parameter -m verwenden und das lokale Skript auf dem Remote-Server ausführen.

plink [email protected] -m local_script.sh

Wenn Maschine A ein Unix-basiertes System ist, können Sie Folgendes verwenden:

ssh [email protected] 'bash -s' < local_script.sh

Sie sollten das Skript nicht auf den Remote-Server kopieren müssen, um es auszuführen.

1119
Jason R. Coombs

Dies ist eine alte Frage, und Jasons Antwort funktioniert einwandfrei, aber ich möchte Folgendes hinzufügen:

ssh [email protected] <<'ENDSSH'
#commands to run on remote Host
ENDSSH

Dies kann auch mit su und Befehlen verwendet werden, die Benutzereingaben erfordern. (beachte den ' entkommenen Heredoc)

Edit: Da diese Antwort immer mehr Verkehr erhält, würde ich dieser wunderbaren Verwendung von heredoc noch mehr Informationen hinzufügen:

Sie können Befehle mit dieser Syntax verschachteln, und das ist die einzige Möglichkeit, wie das Verschachteln zu funktionieren scheint (auf vernünftige Weise).

ssh [email protected] <<'ENDSSH'
#commands to run on remote Host
ssh [email protected] <<'END2'
# Another bunch of commands on another Host
wall <<'ENDWALL'
Error: Out of cheese
ENDWALL
ftp ftp.secureftp-test.com <<'ENDFTP'
test
test
ls
ENDFTP
END2
ENDSSH

Sie können sich tatsächlich mit einigen Diensten wie Telnet, FTP usw. unterhalten. Denken Sie jedoch daran, dass heredoc die stdin nur als Text sendet und nicht auf eine Antwort zwischen den Zeilen wartet

Bearbeiten: Ich habe gerade herausgefunden, dass Sie die Innenseiten mit Tabulatoren einrücken können , wenn Sie <<-END verwenden!

ssh [email protected] <<-'ENDSSH'
    #commands to run on remote Host
    ssh [email protected] <<-'END2'
        # Another bunch of commands on another Host
        wall <<-'ENDWALL'
            Error: Out of cheese
        ENDWALL
        ftp ftp.secureftp-test.com <<-'ENDFTP'
            test
            test
            ls
        ENDFTP
    END2
ENDSSH

(Ich denke das sollte funktionieren)

Siehe auch http://tldp.org/LDP/abs/html/here-docs.html

569
Yarek T

Vergessen Sie auch nicht, Variablen zu maskieren, wenn Sie sie vom Ziel-Host abholen möchten.

Das hat mich in der Vergangenheit erwischt.

Zum Beispiel:

[email protected]> ssh [email protected] "echo \$HOME"

druckt/home/user2 aus

während

[email protected]> ssh [email protected] "echo $HOME"

druckt/home/user aus

Ein anderes Beispiel:

[email protected]> ssh [email protected] "echo hello world | awk '{print \$1}'"

druckt "Hallo" richtig aus.

235
dogbane

Dies ist eine Erweiterung der Antwort von YarekT, um Inline-Remote-Befehle mit der Übergabe von ENV-Variablen vom lokalen Computer an den Remote-Host zu kombinieren, sodass Sie Ihre Skripte auf der Remote-Seite parametrisieren können:

ssh [email protected] ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
  # commands to run on remote Host
  echo $ARG1 $ARG2
ENDSSH

Ich fand das außerordentlich hilfreich, indem ich alles in einem Skript hielt, damit es sehr lesbar und wartbar ist.

Warum funktioniert das? ssh unterstützt die folgende Syntax:

ssh user @ Host remote_command

In bash können wir Umgebungsvariablen angeben, die definiert werden müssen, bevor ein Befehl in einer einzelnen Zeile ausgeführt wird:

ENV_VAR_1 = 'value1' ENV_VAR_2 = 'value2' bash -c 'echo $ ENV_VAR_1 $ ENV_VAR_2'

Das macht es einfach, Variablen vor dem Ausführen eines Befehls zu definieren. In diesem Fall ist Echo unser Befehl, den wir ausführen. Alles vor dem Echo definiert Umgebungsvariablen.

Wir kombinieren also diese beiden Funktionen und YarekTs Antwort, um Folgendes zu erhalten:

ssh user @ Host ARG1 = $ ARG1 ARG2 = $ ARG2 'bash -s' << 'ENDSSH' ...

In diesem Fall setzen wir ARG1 und ARG2 auf lokale Werte. Alles nach user @ Host als remote_command senden. Wenn die Remote-Maschine den Befehl ARG1 ausführt und ARG2 die lokalen Werte festlegt, führt sie dank der lokalen Befehlszeilenauswertung, die Umgebungsvariablen auf dem Remote-Server definiert, den Befehl bash -s mit diesen Variablen aus. Voila.

144
chubbsondubs
<hostA_Shell_Prompt>$ ssh [email protected] "ls -la"

Dadurch werden Sie zur Eingabe eines Kennworts aufgefordert, es sei denn, Sie haben den öffentlichen Schlüssel Ihres hostA-Benutzers in die Datei authorized_keys im Verzeichnis des Benutzers .ssh kopiert. Dies ermöglicht eine passwortlose Authentifizierung (wenn dies in der Konfiguration des SSH-Servers als Authentifizierungsmethode akzeptiert wird).

100
Vinko Vrsalovic

Ich habe begonnen, Fabric für komplexere Operationen zu verwenden. Fabric erfordert Python und einige andere Abhängigkeiten, jedoch nur auf dem Clientcomputer. Der Server muss nur ein SSH-Server sein. Ich finde dieses Tool viel leistungsfähiger als an SSH übergebene Shell-Skripte und es lohnt sich, es einzurichten (insbesondere, wenn Sie gerne in Python programmieren). Fabric verarbeitet das Ausführen von Skripten auf mehreren Hosts (oder Hosts bestimmter Rollen), erleichtert idempotente Vorgänge (z. B. das Hinzufügen einer Zeile zu einem Konfigurationsskript, jedoch nicht, wenn es bereits vorhanden ist) und ermöglicht die Erstellung komplexerer Logik (z. B. Python Sprache zur Verfügung stellen kann).

27
Jason R. Coombs

Versuchen Sie, ssh [email protected] sh ./script.unx auszuführen.

10
Jeremy

Angenommen, Sie möchten dies automatisch von einem "lokalen" Computer aus tun, ohne sich manuell bei dem "entfernten" Computer anzumelden, sollten Sie sich eine TCL-Erweiterung ansehen, die als "Expect" bezeichnet wird. Sie ist genau für diese Art von Situation ausgelegt. Ich habe auch einen Link zu einem Skript zum Anmelden/Interagieren über SSH bereitgestellt.

https://www.nist.gov/services-resources/software/expect

http://bash.cyberciti.biz/security/expect-ssh-login-script/

9
George Jempty

Ich verwende dieses Skript, um ein Shell-Skript auf einem Remote-Computer auszuführen (getestet auf/bin/bash):

ssh [email protected] . /home/deploy/path/to/script.sh
3
Is Ma

wenn Sie einen Befehl wie diesen ausführen möchten, verursacht der Befehl temp=`ls -a` echo $temp in `` Fehler.

der folgende Befehl löst das Problem ssh [email protected] ''' temp=`ls -a` echo $temp '''

2
Jinmiao Luo

Die Antwort hier ( https://stackoverflow.com/a/2732991/475288 ) funktioniert hervorragend, wenn Sie versuchen, ein Skript auf einem entfernten Linux-Computer mit plink oder ssh. Es funktioniert, wenn das Skript mehrere Zeilen in linux enthält.

** Wenn Sie jedoch versuchen, ein Batch-Skript auszuführen, das sich auf einem lokalen linux/windows Computer befindet, und Ihr Remote-Computer Windows ist und aus mehreren Zeilen besteht, die Folgendes verwenden: **

plink [email protected] -m local_script.bat

wird nicht funktionieren.

Nur die erste Zeile des Skripts wird ausgeführt. Dies ist wahrscheinlich eine Einschränkung von plink.

Lösung 1:

So führen Sie ein mehrzeiliges Stapelskript aus (insbesondere, wenn es relativ einfach ist und aus wenigen Zeilen besteht):

Wenn Ihr ursprüngliches Stapelskript wie folgt lautet

cd C:\Users\ipython_user\Desktop 
python filename.py

sie können die Zeilen mithilfe des Trennzeichens "&&" wie folgt in Ihrer local_script.bat -Datei kombinieren: https://stackoverflow.com/a/8055390/475288 :

cd C:\Users\ipython_user\Desktop && python filename.py

Nach dieser Änderung können Sie das Skript wie hier von @ JasonR.Coombs beschrieben ausführen: https://stackoverflow.com/a/2732991/475288 mit:

`plink [email protected] -m local_script.bat`

Lösung 2:

Wenn Ihr Stapelskript relativ kompliziert ist, ist es möglicherweise besser, ein Stapelskript zu verwenden, das den Befehl plink sowie die folgenden Elemente enthält, auf die hier von @Martin https://stackoverflow.com/a/32196999/4752883 hingewiesen wird :

rem Open tunnel in the background
start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i "[SSH
key]" -N

rem Wait a second to let Plink establish the tunnel 
timeout /t 1

rem Run the task using the tunnel
"C:\Program Files\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R

rem Kill the tunnel
taskkill /im plink.exe
1
alpha_989
cat ./script.sh | ssh <user>@<Host>
0
Amir

Dieses Bash-Skript führt ssh auf einem Remote-Zielcomputer aus und führt einen Befehl auf dem Remote-Computer aus. Vergessen Sie nicht, expect zu installieren, bevor Sie es ausführen (auf Mac brew install expect).

#!/usr/bin/expect
set username "enterusenamehere"
set password "enterpasswordhere"
set hosts "enteripaddressofhosthere"
spawn ssh  [email protected]$hosts
expect "[email protected]$hosts's password:"
send -- "$password\n"
expect "$"
send -- "somecommand on target remote machine here\n"
sleep 5
expect "$"
send -- "exit\n"
0
Mohammed Rafeeq
ssh [email protected] ".~/.bashrc;/cd path-to-file/;.filename.sh"

es wird dringend empfohlen, die Umgebungsdatei (.bashrc/.bashprofile/.profile) als Quelle zu verwenden. bevor Sie etwas auf einem Remote-Host ausführen, da die Umgebungsvariablen des Ziel- und des Quellhosts möglicherweise verschoben werden.

0
Ankush Sahu