Comment utiliser SSH pour exécuter un script shell sur une machine distante?

je dois exécuter un script shell (windows/Linux) sur une machine distante.

j'ai configuré SSH sur les machines A et B. mon script est sur la machine A qui exécutera une partie de mon code sur une machine distante, la machine B.

les ordinateurs locaux et distants peuvent être des systèmes Windows ou Unix.

y a-t-il un moyen d'exécuter do this using plink/ssh?

1038
demandé sur alpha_989 2008-11-20 14:44:25
la source

12 ответов

si la Machine A est une fenêtre Windows, vous pouvez utiliser Plink (partie de PuTTY ) avec le paramètre-m, et il exécutera le script local sur le serveur distant.

plink [email protected] -m local_script.sh

si la Machine A est un système Unix, vous pouvez utiliser:

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

Vous ne devriez pas avoir à copier le script sur le serveur distant à exécuter.

1050
répondu Jason R. Coombs 2010-04-29 01:00:03
la source

C'est une vieille question, et la réponse de Jason fonctionne bien, mais je voudrais ajouter ceci:

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

cela peut également être utilisé avec su et les commandes qui nécessitent une entrée utilisateur. (notez le ' échappé heredoc)

Edit: puisque cette réponse ne cesse de recevoir des bouts de trafic, Je voudrais ajouter encore plus d'informations à cette utilisation merveilleuse de heredoc:

vous pouvez insérer des commandes avec cette syntaxe, et c'est la seule façon de au travail (en danger)

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

vous pouvez effectivement avoir une conversation avec certains services comme telnet, ftp, etc. Mais rappelez-vous qu'heredoc envoie simplement le stdin sous forme de texte, il n'attend pas de réponse entre les lignes

Edit: je viens de découvrir que vous pouvez indenter l'intérieur si vous utilisez <<-END !

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

(je pense que cela devrait fonctionner)

Voir Aussi http://tldp.org/LDP/abs/html/here-docs.html

518
répondu Yarek T 2017-05-30 19:20:22
la source

Aussi, n'oubliez pas d'échapper à des variables si vous voulez ramasser de l'hôte de destination.

cela m'a surpris dans le passé.

par exemple:

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

imprime /home/user2

alors que

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

imprime /home/user

autre exemple:

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

imprime "bonjour" correctement.

213
répondu dogbane 2008-11-20 15:25:35
la source

il s'agit d'une extension de la réponse de YarekT pour combiner les commandes à distance en ligne avec la transmission des variables ENV de la machine locale à l'hôte distant afin que vous puissiez paramétrer vos scripts du côté distant:

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

j'ai trouvé cela exceptionnellement utile en gardant tout dans un script de sorte qu'il est très lisible et maintenable.

pourquoi ça marche. ssh supporte la syntaxe suivante:

SSH [email protected] remote_command

dans bash nous pouvons spécifier des variables d'environnement à définir avant d'exécuter une commande sur une seule ligne comme so:

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

qui rend facile de définir des variables avant d'exécuter une commande. Dans ce cas, echo est notre commandement. Tout ce qui précède echo définit les variables d'environnement.

nous combinons donc ces deux caractéristiques et la réponse de YarekT pour obtenir:

SSH [email protected] ARG1= $ ARG1 ARG2= $ ARG2 'bash-s' <<'ENDSSH'...

dans ce cas, nous réglons ARG1 et ARG2 aux valeurs locales. Envoyer tout après [email protected] comme le remote_command. Lorsque la machine distante exécute la commande ARG1 et ARG2, les valeurs locales sont définies, grâce à l'évaluation de la ligne de commande locale, qui définit les variables d'environnement sur le serveur distant, puis exécute la commande bash-s en utilisant ces variables. Le tour est joué.

130
répondu chubbsondubs 2017-08-01 17:59:36
la source
<hostA_shell_prompt>$ ssh [email protected] "ls -la"

qui vous demandera un mot de passe, à moins que vous n'ayez copié la clé publique de votre hostA user sur le fichier authorized_keys de la maison de l'utilisateur .ssh du répertoire. Cela permettra une authentification sans mot de passe (si acceptée comme méthode auth sur la configuration du serveur ssh)

91
répondu Vinko Vrsalovic 2008-11-20 14:53:18
la source

j'ai commencé à utiliser tissu pour des opérations plus sophistiquées. Fabric nécessite Python et quelques autres dépendances, mais seulement sur la machine client. Le serveur ne doit être qu'un serveur ssh. Je trouve que cet outil est beaucoup plus puissant que les scripts shell distribués à SSH, et vaut bien la peine d'être configuré (surtout si vous aimez programmer en Python). Fabric gère l'exécution de scripts sur plusieurs hôtes( ou hôtes de certains rôles), aide faciliter les opérations idempotent (comme ajouter une ligne à un script de configuration, mais pas si elle est déjà là), et permettre la construction de la logique plus complexe (comme le langage Python peut fournir).

24
répondu Jason R. Coombs 2016-11-18 17:13:18
la source

en supposant que vous voulez dire que vous voulez faire cela automatiquement à partir d'une machine "locale", sans se connecter manuellement à la machine "distante", vous devriez regarder dans une extension TCL connue sous le nom D'Expect, il est conçu précisément pour ce genre de situation. C'est la page d'accueil ci-dessous qui semble un peu merdique, mais ne laissez pas cela vous dissuader; j'ai aussi fourni un lien vers un script pour se connecter/interagir via SSH.

http://expect.nist.gov /

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

8
répondu George Jempty 2008-11-20 15:10:10
la source

Essayez d'exécuter ssh [email protected] sh ./script.unx .

8
répondu Jeremy 2018-02-28 12:52:54
la source

la réponse ici ( https://stackoverflow.com/a/2732991/4752883 ) fonctionne bien si vous essayez d'exécuter un script sur une machine linux distante en utilisant plink ou ssh . Cela fonctionnera si le script a plusieurs lignes sur linux .

* * cependant, si vous essayez d'exécuter un script batch situé sur un local linux/windows machine et votre machine à distance est Windows , et il se compose de lignes multiples en utilisant * *

plink [email protected] -m local_script.bat

ne marchera pas.

seule la première ligne du script sera exécutée. C'est probablement un limitation de plink .

Solution 1:

pour exécuter un script de traitement par lots multilignes (surtout si c'est relativement simple), composé de quelques lignes):

si votre script de lot original est comme suit""

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

vous pouvez combinez les lignes ensemble en utilisant le séparateur "&&" comme suit dans votre local_script.bat fichier: https://stackoverflow.com/a/8055390/4752883 :

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

après ce changement, vous pouvez exécuter le script comme indiqué ici par @JasonR.Coombs: https://stackoverflow.com/a/2732991/4752883 avec:

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

Solution 2:

si votre script de lot est relativement compliqué, il peut être préférable d'utiliser un lot script qui encapsule la commande plink ainsi que les éléments suivants comme indiqué ici par @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
répondu alpha_989 2018-04-21 06:53:49
la source

ce script bash fait ssh dans une machine distante cible, et exécute une commande dans la machine distante, n'oubliez pas d'installer expect avant de l'exécuter (sur 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
répondu Mohammed Rafeeq 2018-05-30 12:22:42
la source

si vous voulez exécuter une commande comme celle-ci temp=`ls -a` echo $temp commande dans ` va provoquer des erreurs.

La commande

ci-dessous résoudra ce problème ssh [email protected] ''' temp=`ls -a` echo $temp '''

0
répondu Jinmiao Luo 2018-09-21 06:31:48
la source

d'abord, Copiez le script sur la Machine B en utilisant scp

[[email protected]]$ scp /chemin/vers/le / script [email protected]:/home/user/path

ensuite, il suffit d'exécuter le script

[[email protected]]$ ssh [email protected] "/home/utilisateur/chemin/script"

cela fonctionnera si vous avez donné une permission exécutable au script.

-22
répondu Baishampayan Ghose 2015-07-08 20:38:45
la source

Autres questions sur ssh shell sysadmin remote-execution