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


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

Ich habe SSH auf beiden Maschinen A und B konfiguriert. Mein Skript ist auf der Maschine A, die einen Teil meines Codes auf einem Remote-Computer, Maschine B, ausführen wird.

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

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


1010
2017-11-20 11:44


Ursprung


Antworten:


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

plink root@MachineB -m local_script.sh

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

ssh root@MachineB 'bash -s' < local_script.sh

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


1025
2018-04-28 20:41



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

ssh user@host <<'ENDSSH'
#commands to run on remote host
ENDSSH

Dies kann auch mit su und Befehlen, die eine Benutzereingabe erfordern, verwendet werden. (beachten Sie das ' entkam heredoc)

Edit: Da diese Antwort immer mehr Traffic bringt, würde ich noch mehr Informationen zu diesem wunderbaren Einsatz von herec hinzufügen:

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

ssh user@host <<'ENDSSH'
#commands to run on remote host
ssh user@host2 <<'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 tatsächlich mit einigen Diensten wie telnet, ftp usw. telefonieren. Aber denken Sie daran, dass heredoc nur die stdin als Text sendet, es wartet nicht auf die Antwort zwischen den Zeilen

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

ssh user@host <<-'ENDSSH'
    #commands to run on remote host
    ssh user@host2 <<-'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


506
2017-10-06 13:11



Vergessen Sie außerdem nicht, Variablen zu flüchten, wenn Sie sie vom Zielhost abholen wollen.

Das hat mich in der Vergangenheit gefangen.

Beispielsweise:

user@host> ssh user2@host2 "echo \$HOME"

druckt aus / home / user2

während

user@host> ssh user2@host2 "echo $HOME"

druckt aus / home / user

Ein anderes Beispiel:

user@host> ssh user2@host2 "echo hello world | awk '{print \$1}'"

gibt "Hallo" richtig aus.


212
2017-11-20 12:25



Dies ist eine Erweiterung von YarekT's Antwort zum Kombinieren von Inline-Remote-Befehlen mit Übergabe von ENV-Variablen vom lokalen Rechner an den Remote-Host, so dass Sie Ihre Skripte auf der Remote-Seite parametrisieren können:

ssh user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
  # commands to run on remote host
  echo $ARG1 $ARG2
ENDSSH

Ich fand das außergewöhnlich hilfreich, indem ich alles in einem Skript aufbewahre, damit es gut lesbar und wartbar ist.

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

ssh user @ host remote_command

In bash können wir Umgebungsvariablen angeben, die vor der Ausführung eines Befehls in einer einzelnen Zeile definiert werden:

ENV_VAR_1 = 'Wert1' ENV_VAR_2 = 'Wert2' 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 echo definiert Umgebungsvariablen.

Also kombinieren wir diese beiden Funktionen und die Antwort von YarekT:

ssh Benutzer @ Host ARG1 = $ ARG1 ARG2 = $ ARG2 'Bash -s' << 'ENDSSH' ...

In diesem Fall setzen wir ARG1 und ARG2 auf lokale Werte. Senden Sie alles nach user @ host als remote_command. Wenn der Remote-Computer den Befehl ARG1 und ARG2 ausführt, werden die lokalen Werte dank der lokalen Befehlszeilenauswertung festgelegt, die Umgebungsvariablen auf dem Remote-Server definiert. Anschließend wird der Befehl bash -s mit diesen Variablen ausgeführt. Voila.


124
2017-09-09 15:00



<hostA_shell_prompt>$ ssh user@hostB "ls -la"

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


89
2017-11-20 11:53



Ich habe angefangen zu benutzen Stoff für anspruchsvollere Operationen. Fabric benötigt Python und einige andere Abhängigkeiten, aber nur auf dem Client-Rechner. Der Server muss nur ein SSH-Server sein. Ich finde, dass dieses Tool viel leistungsfähiger ist als Shell-Skripte, die an SSH übergeben werden, und es lohnt sich, sich einzurichten (vor allem, wenn Sie gerne in Python programmieren). Fabric-Handles, die Skripts auf mehreren Hosts (oder Hosts bestimmter Rollen) ausführen, erleichtern idempotente Operationen (z. B. das Hinzufügen einer Zeile zu einem Konfigurationsskript, aber nicht, wenn sie bereits vorhanden sind) und ermöglichen die Konstruktion komplexerer Logik (z. B. Python Sprache kann liefern).


24
2018-01-26 16:17



Angenommen, Sie möchten dies automatisch von einer "lokalen" Maschine aus tun, ohne sich manuell bei der "Remote" -Maschine anzumelden, sollten Sie in eine TCL-Erweiterung namens Expect schauen, die genau auf diese Situation zugeschnitten ist. Die Homepage unten sieht irgendwie beschissen aus, aber lass dich davon nicht abschrecken; Ich habe auch einen Link zu einem Skript für die Anmeldung / Interaktion über SSH zur Verfügung gestellt.

http://expect.nist.gov/

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


8
2017-11-20 12:10



Versuche zu laufen ssh user@remote sh ./script.unx.


7
2017-12-18 21:16



Die Antwort hier (https://stackoverflow.com/a/2732991/4752883) funktioniert super wenn Sie versuchen, ein Skript auf einem Remote-Linux-Computer mit zu starten plink oder ssh. Es funktioniert, wenn das Skript mehrere Zeilen hat linux.

** Wenn Sie jedoch versuchen, ein Stapelscript auf einem lokalen Skript auszuführen linux/windows Maschine und Ihre Remote-Maschine ist Windowsund es besteht von mehreren Zeilen mit **

plink root@MachineB -m local_script.bat

werde nicht arbeiten.

Nur die erste Zeile des Skripts wird ausgeführt. Dies ist wahrscheinlich ein Begrenzung von plink.

Lösung 1:

Um ein mehrzeiliges Batch-Skript auszuführen (besonders wenn es relativ einfach ist, bestehend aus ein paar Zeilen):

Wenn das ursprüngliche Stapelscript wie folgt lautet

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

Sie können die Zeilen mit dem Trennzeichen "&&" wie folgt kombinieren: local_script.bat Datei: https://Stackoverflow.com/a/8055390/4752883:

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

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

`plink root@MachineB -m local_script.bat`

Lösung 2:

Wenn Ihr Stapelscript relativ kompliziert ist, ist es möglicherweise besser, einen Stapel zu verwenden Skript, das den Befehl plink kapselt und wie folgt ausgeführt wird hier bei @Martin https://stackoverflow.com/a/32196999/4752883:

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

0
2018-04-21 00:44



Dieses Bash-Skript führt SSH in einen Ziel-Remote-Rechner ein und führt einen Befehl auf dem Remote-Rechner aus. Vergessen Sie nicht, expect vor dem Ausführen zu installieren (auf dem Mac) brew install expect )

#!/usr/bin/expect
set username "enterusenamehere"
set password "enterpasswordhere"
set hosts "enteripaddressofhosthere"
spawn ssh  $username@$hosts
expect "$username@$hosts's password:"
send -- "$password\n"
expect "$"
send -- "somecommand on target remote machine here\n"
sleep 5
expect "$"
send -- "exit\n"

0
2018-05-30 09:22



Kopieren Sie zuerst das Skript mit scp auf Maschine B

[user @ machineA] $ scp / pfad / zu / script benutzer @ machineB: / home / benutzer / pfad

Führen Sie dann das Skript aus

[Benutzer @ machineA] $ ssh Benutzer @ machineB "/ home / Benutzer / Pfad / Skript"

Dies funktioniert, wenn Sie dem Skript eine ausführbare Berechtigung erteilt haben.


-22