Vraag Hoe voer ik een lokaal bash-script uit op externe machines via ssh?


Ik ben op zoek naar een manier om de configuratie van de ene centrale naar de andere externe machine te duwen zonder dat er iets op de externe machines hoeft te worden geïnstalleerd.

Het doel is om iets te doen zoals je zou vinden met tools zoals cfengine, maar op een set machines waarop geen agents zijn ingesteld. Dit kan eigenlijk een goede manier van opzetten zijn cfagent op een set bestaande externe machines.


45
2017-12-23 18:41


oorsprong


Gelijkaardig op SO: stackoverflow.com/q/305035/435605 - AlikElzin-kilaka
De eigenlijke vragen hebben 23 upvotes waar het duplicaat op SO 55 heeft: P - MoJo


antwoorden:


Je kunt een script doorgeven en het ephemerally laten uitvoeren door het in te pipen en een shell uit te voeren.

bijv.

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

Natuurlijk, de "ls -l; echo 'Hello World'" deel kan worden vervangen door een bash-script dat is opgeslagen in een bestand op de lokale computer.

bijv.

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

Proost!


51
2017-12-23 18:47



Hoe laat ik dit uitvoeren als sudo op het externe systeem.e.g. Als ik op de externe server was ingelogd, zou ik dit meestal uitvoeren als sudo -u testuser script.sh - Sharjeel
Wat als het script dat ik bel gebruikersinteracties impliceert ??? - Abhimanyu Srivastava


Er zijn verschillende manieren om het te doen.

1:

ssh user@remote_server 'bash -s' < localfile

2:

cat localfile  | ssh user@remote_server

3:

ssh user@remote_server "$(< localfile)"

nummer 3 is mijn voorkeur, het maakt interactieve commando's b.v. su -S service nginx restart 

(# 1 zal de rest van het script gebruiken als invoer voor de wachtwoordvraag wanneer u dit gebruikt su -S.)


18
2018-05-15 08:41



Wat betreft het uitvoeren van lokaal script op externe machine - Is er een manier om variabele als een argument naar de externe machine te sturen ..? d.w.z. samen met het script wil ik een variabele (met meerdere regels) verzenden als argument naar de externe machine. Het script is dan van plan om de variabele te gebruiken.


Ik zou Python's Fabric voor dit doel aanbevelen:

#!/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

U moet bovenstaande kunnen gebruiken om aan de slag te gaan. Raadpleeg het uitstekende product van Fabric documentatie om de rest te doen. Als addendum is het volledig mogelijk om je script volledig binnen Fabric te schrijven - kopiëren is niet nodig, maar het is belangrijk om te weten dat als je het script op alle computers wilt wijzigen, je alleen de lokale kopie en herdistributie hoeft te bewerken. Bovendien kunt u met een beetje meer dan het basisgebruik van de API het script aanpassen op basis van de host waarop het momenteel wordt uitgevoerd en / of andere variabelen. Het is een soort van pythonic Expect.


12
2017-12-23 20:33



Ik denk niet dat dit precies de vraag beantwoordt, maar ik vind het een goed idee en ik zag Fabric als een handig hulpmiddel. - tremoloqui
@tremoloqui Fabric is een python-wrapper rond ssh - niets hoeft op de doelmachines te worden geïnstalleerd, behalve dat het script wordt gepusht. Die, indien herschreven als een reeks Fabric-commando's (met run en sudo), is zelfs niet nodig. - Izkata


Dit is precies waar Ansible voor wordt gebruikt. Er is geen agent, u hoeft alleen maar een tekstbestand te maken met de naam:

/etc/ansible/hosts

met inhoud die er ongeveer zo uitziet:

[webhosts]
web[1-8]

Dit zou specificeren dat machines "web1, web2 ... web8" in de groep "webhosts" staan. Dan kun je dingen doen als:

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

om de apache2-service op al uw machines opnieuw te starten met behulp van sudo.

Je kunt doen op de vliegende opdrachten zoals:

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

of u kunt een lokaal script uitvoeren op de externe computer:

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

of u kunt een Playbook maken (raadpleeg de documentatie voor meer informatie) met een volledige configuratie die u wilt dat uw servers conformeren aan en implementeren met:

ansible-playbook webplaybook.yml

In principe kunt u het gebruiken als een commandoregeltool voor het uitvoeren van opdrachten op meerdere servers en het gebruik ervan uitbreiden naar een complete configuratietool naar eigen inzicht.


5
2017-08-15 09:35



Ik hou net zo van anicie als de volgende man, maar als hij vraagt ​​naar een script, dan heeft ansible een hele leuke scriptmodule: ansible webhosts -m script script.sh - ptman
Alle andere antwoorden bevatten een bash-script, maar het is niet waar hij specifiek om vroeg. Hij zei zojuist dat hij configuratie naar externe machines dreef. Maar goede vermelding van de scriptmodule :) - seumasmac
Stem alstublieft op dit antwoord! Dit is de manier om het te doen! - chicks
@ptman Ik heb net gemerkt dat hij, terwijl hij geen script in de vraag vermeldt, in de titel staat! Sorry. Ik ben bijgewerkt. - seumasmac


Zoals uitgelegd in dit antwoord je kunt gebruiken heredoc :

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

Je moet voorzichtig zijn met heredoc, omdat het gewoon tekst verzendt, maar het wacht niet echt op het antwoord. Dat betekent dat het niet zal wachten tot je opdrachten worden uitgevoerd.


3
2017-12-13 14:24





Het antwoord hier (https://stackoverflow.com/a/2732991/4752883) werkt uitstekend als u een script probeert uit te voeren op een linux op afstand machine gebruiken plink of ssh. Het zal werken als het script meerdere regels bevat linux.

** Echter, als u dat bent proberen een batch-script uit te voeren op een lokaal linux/windowsmachine en uw externe machine is Windowsen het bestaat uit meerdere regels met **

plink root@MachineB -m local_script.bat

het zal niet werken.

Alleen de eerste regel van het script zal worden uitgevoerd. Dit is waarschijnlijk een beperking van plink.

Oplossing 1:

Een batchscript met meerdere regels uitvoeren (vooral als het relatief eenvoudig is, bestaande uit een paar regels):

Als uw oorspronkelijke batch-script als volgt is

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

je kunt de lijnen samen combineren met het "&&" scheidingsteken als volgt in je local_script.bat bestand als volgt https://stackoverflow.com/a/8055390/4752883:

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

Na deze wijziging kunt u het script uitvoeren zoals hier aangegeven @ JasonR.Coombs: https://stackoverflow.com/a/2732991/4752883

Oplossing 2:

Als uw batchtype relatief ingewikkeld is, is het misschien beter om een ​​batch te gebruiken script dat de plinkopdracht inkapselt en volgt als aangegeven hier door @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





Waarom kopieer je niet gewoon eerst het script en laat je het dan draaien?

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

Natuurlijk moet je oppassen dat je het niet uploadt naar een plaats die beschrijfbaar is voor de hele wereld, dus niemand anders zou ermee kunnen fouilleren voordat je het uitvoert (mogelijk als root).


0
2017-12-23 19:00



De reden dat ik het script niet wil uploaden, is dat het niet hoeft te worden beheerd en de risico's heeft die je hebt genoemd. Het lijkt mij ook dat het eenvoudiger is dan het meerstapsproces van uploaden, verwerken en (optioneel) verwijderen. - tremoloqui


Herschrijf het script op een manier die elke opdracht al bevat is voorafgegaan door ssh en een hostnaam / ip of een lijst hiervan wordt als een argument aan het script doorgegeven (ervan uitgaande dat je wachtwoordloze / ssh-agent-sleutelverificatie hebt ingesteld). Sommige werkzaamheden kunnen nodig zijn om fout / retourcodes op de juiste manier door de afstandsbedieningsopdrachten te leiden ....


0
2017-12-13 14:31