Frage Wie führe ich ein lokales Bash-Skript auf entfernten Rechnern über ssh aus?


Ich suche nach einer Möglichkeit, die Konfiguration von einer zentralen Maschine auf mehrere entfernte Maschinen zu übertragen, ohne dass irgendetwas auf den entfernten Maschinen installiert werden muss.

Das Ziel ist es, etwas zu tun, wie Sie es mit Werkzeugen wie cfengine, aber auf einer Reihe von Rechnern, auf denen keine Agenten eingerichtet sind. Dies könnte tatsächlich eine gute Technik der Einrichtung sein cfagent auf einer Reihe von vorhandenen Remote-Maschinen.


45
2017-12-23 18:41


Ursprung


Ähnlich auf SO: stackoverflow.com/q/305035/435605 - AlikElzin-kilaka
Die eigentliche Frage hat 23 upvotes, wo das Duplikat auf SO 55: P hat - MoJo


Antworten:


Sie können ein Skript übergeben und es ephemer ausführen lassen, indem Sie es einbinden und eine Shell ausführen.

z.B.

echo "ls -l; echo 'Hello World'" | ssh me@myserver /bin/bash

Natürlich, die "ls -l; echo 'Hello World'" Teil könnte durch ein Bash-Skript ersetzt werden, das in einer Datei auf dem lokalen Rechner gespeichert ist.

z.B.

cat script.sh | ssh me@myserver /bin/bash

Prost!


51
2017-12-23 18:47



Wie mache ich das als sudo auf dem Remote-System.e.g. Wenn ich am Remote-Server angemeldet wäre, würde ich das normalerweise als sudo -u testuser script.sh ausführen - Sharjeel
Was passiert, wenn das Skript, das ich anrufe, Benutzerinteraktionen beinhaltet ??? - Abhimanyu Srivastava


Es gibt mehrere Möglichkeiten, dies zu tun.

1:

ssh user@remote_server 'bash -s' < localfile

2:

cat localfile  | ssh user@remote_server

3:

ssh user@remote_server "$(< localfile)"

Nummer 3 ist mein bevorzugter Weg, es ermöglicht interaktive Befehle, z. su -S service nginx restart 

(# 1 wird den Rest des Skripts als Eingabe für die Passwortfrage verwenden, wenn Sie es verwenden su -S.)


18
2018-05-15 08:41



In Bezug auf das Ausführen von lokalen Skript auf Remote-Computer - Gibt es eine Möglichkeit, Variable als Argument an den Remote-Rechner zu senden ..? d. h. zusammen mit dem Skript möchte ich eine Variable (mit mehreren Zeilen) als Argument an den entfernten Rechner senden. Das Skript beabsichtigt dann, die Variable zu verwenden.


Ich würde Pythons Fabric für diesen Zweck empfehlen:

#!/usr/bin/python
# ~/fabfile.py

from fabric_api import *

env.hosts = ['host1', 'host2']
def deploy_script():
    put('your_script.sh', 'your_script.sh', mode=0755)
    sudo('./your_script.sh')

# from shell
$ fab deploy_script

Sie sollten in der Lage sein, das oben genannte zu verwenden, um zu beginnen. Wenden Sie sich an Fabric ist ausgezeichnet Dokumentation um den Rest zu machen. Als Addendum ist es völlig möglich, Ihr Skript vollständig in Fabric zu schreiben - es ist kein Kopieren erforderlich. Es sollte jedoch beachtet werden, dass Sie zum Ändern des Skripts auf allen Computern nur die lokale Kopie bearbeiten und erneut bereitstellen müssen. Darüber hinaus können Sie das Skript mit etwas mehr als der grundlegenden Verwendung der API auf der Grundlage des Hosts, auf dem es gerade ausgeführt wird, und / oder anderer Variablen ändern. Es ist eine Art Python Erwarten.


12
2017-12-23 20:33



Ich glaube nicht, dass dies genau die Frage beantwortet, aber ich mag die Idee und ich könnte Stoff als nützliches Werkzeug sehen. - tremoloqui
@tremoloqui Fabric ist ein Python-Wrapper um ssh - nichts muss auf den Zielrechnern installiert werden, das Skript muss gespeichert werden. Was, wenn es als eine Reihe von Fabric-Befehlen umgeschrieben wird (unter Verwendung von run und sudo), wird nicht einmal benötigt. - Izkata


Genau dafür wird Ansible verwendet. Es gibt keinen Agenten, Sie müssen nur eine Textdatei erstellen mit dem Namen:

/etc/ansible/hosts

mit Inhalt, der ungefähr so ​​aussieht:

[webhosts]
web[1-8]

Dies würde spezifizieren, dass Maschinen "web1, web2 ... web8" in der Gruppe "webhosts" sind. Dann können Sie Dinge tun wie:

ansible webhosts -m service -a "name=apache2 state=restarted" --sudo

Starten Sie den apache2-Dienst auf allen Ihren Computern mit sudo neu.

Sie können im Handumdrehen Befehle wie:

ansible webhosts -m shell -a "df -h"

oder Sie können ein lokales Skript auf dem Remote-Computer ausführen:

ansible webhosts -m script -a "./script.sh"

oder Sie können ein Playbook erstellen (lesen Sie die Dokumentation für Details) mit einer vollständigen Konfiguration, die Sie Ihren Servern anpassen und bereitstellen möchten:

ansible-playbook webplaybook.yml

Grundsätzlich können Sie es als Befehlszeilenprogramm zum Ausführen von Befehlen auf mehreren Servern verwenden und seine Verwendung nach Bedarf in ein vollständiges Konfigurationstool ausweiten.


5
2017-08-15 09:35



Ich mag so gut wie der nächste Kerl, aber wenn er nach einem Drehbuch fragt, dann hat Ansible ein wirklich nettes Wort Skriptmodul: ansible webhosts -m script script.sh - ptman
Alle anderen Antworten beinhalten ein Bash-Skript, aber es ist nicht das, wonach er speziell gefragt hat. Er hat gerade gesagt, dass man die Konfiguration auf Remote-Maschinen schieben soll. Aber gute Erwähnung des Skriptmoduls :) - seumasmac
Bitte stimmen Sie diese Antwort ab! So geht es! - chicks
@ptman Ich habe gerade erst gemerkt, dass er zwar kein Skript in der Frage erwähnt, er tut es aber im Titel! Es tut uns leid. Ich habe aktualisiert. - seumasmac


Wie in diese Antwort Sie können verwenden Heredoc :

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

Sie müssen vorsichtig sein mit heredoc, weil es nur Text sendet, aber es wartet nicht wirklich auf die Antwort. Das heißt, es wird nicht auf die Ausführung Ihrer Befehle warten.


3
2017-12-13 14:24





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

** Allerdings, wenn Sie es sind versuchen, ein Batch-Skript auf einem lokalen ausführen linux/windowsMaschine und Ihre Remote-Maschine ist Windows, und es besteht aus mehreren Zeilen mit **

plink root@MachineB -m local_script.bat

es wird nicht funktionieren.

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 wie folgt 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

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

1
2018-04-19 21:09





Warum nicht einfach das Skript kopieren und dann ausführen?

scp your_script.sh the_server:
ssh the_server "chmod +x your_script.sh; ./your_script.sh"

Natürlich solltest du darauf achten, dass du es nicht an einen weltweit beschreibbaren Ort hochlädst, damit niemand anderes damit herumspielen kann, bevor du es ausführst (möglicherweise als root).


0
2017-12-23 19:00



Der Grund, warum ich das Skript nicht hochladen möchte, ist, dass es nicht verwaltet werden muss und die von Ihnen erwähnten Risiken aufweist. Außerdem scheint es mir einfacher zu sein als der mehrstufige Prozess des Hochladens, Bearbeitens und (optional) Löschens. - tremoloqui


Schreiben Sie das Skript so um, dass jeder Befehl bereits darin enthalten ist ist Präfix ssh und ein Hostname / ip oder eine Liste von solchen wird als Argument an das Skript übergeben (vorausgesetzt, Sie haben die Authentifizierung mit passwordless / ssh-agent key eingerichtet). Einige Arbeiten sind möglicherweise erforderlich, um Fehler- / Rückgabecodes korrekt von den Remote-Befehlen zurückzugeben ....


0
2017-12-13 14:31





Wenn das Skript nicht zu groß ist und Sie bash oder ksh verwenden ...

ssh vm24 -t bash -c "$(printf "%q" "$(< shell-test.sh )")"

Sowohl stdin als auch stdout funktionieren korrekt, aber das Skript ist auf die Argumentgröße beschränkt (normalerweise etwa 100k). Argumente für das Skript funktionieren möglicherweise am Ende der Zeile, möglicherweise nach einem zusätzlichen "-" Argument. Das "-t" zum Zuweisen einer Pty ist optional.

Achtung: Dies verwirrt die Bash-Vervollständigung, nicht die Tab-Taste.


0
2018-03-16 23:32