90 votes

Comment exécuter une commande à distance via ssh avec des arguments ?

Dans mon .bashrc Je définis une fonction que je pourrai utiliser ultérieurement sur la ligne de commande :

function mycommand() {
    ssh user@123.456.789.0 cd testdir;./test.sh "$1"
}

Lors de l'utilisation de cette commande, seul le cd est exécutée sur l'hôte distant ; la commande test.sh est exécutée sur l'hôte local. Cela est dû au fait que le point-virgule sépare deux commandes différentes : la commande ssh et la commande test.sh commandement.

J'ai essayé de définir la fonction comme suit (notez les guillemets simples) :

function mycommand() {
    ssh user@123.456.789.0 'cd testdir;./test.sh "$1"'
}

J'ai essayé de garder le cd et la commande test.sh ensemble, mais l'argument $1 n'est pas résolu, indépendamment de ce que je donne à la fonction. On essaie toujours d'exécuter une commande

./test.sh $1

sur l'hôte distant.

Comment puis-je définir correctement mycommand donc le script test.sh est exécuté sur l'hôte distant après être passé dans le répertoire testdir avec la possibilité de transmettre l'argument donné à mycommand à test.sh ?

115voto

konsolebox Points 21338

Faites-le plutôt de cette façon :

function mycommand {
    ssh user@123.456.789.0 "cd testdir;./test.sh \"$1\""
}

Vous devez toujours transmettre l'ensemble de la commande sous la forme d'une chaîne unique, mais dans cette chaîne unique, vous devez avoir $1 élargi avant d'être envoyé à ssh, vous devez donc utiliser "" pour cela.

Mise à jour

Une autre façon correcte de procéder est d'utiliser printf %q pour citer correctement l'argument. Cela rendrait l'argument sûr à analyser même s'il contient des espaces, des guillemets simples, des guillemets doubles ou tout autre caractère qui pourrait avoir une signification spéciale pour l'interpréteur de commandes :

function mycommand {
    printf -v __ %q "$1"
    ssh user@123.456.789.0 "cd testdir;./test.sh $__"
}
  • Lorsque vous déclarez une fonction avec function , () n'est pas nécessaire.
  • Ne faites pas de commentaires à ce sujet juste parce que vous êtes un POSIXiste.

À partir de la version 4.4 de Bash, il peut également être simplifié comme suit :

function mycommand {
    ssh user@123.456.789.0 "cd testdir;./test.sh ${1@Q}"
}

Voir ${parameter@operator} section dans Expansion des paramètres de l'enveloppe .

10voto

Cyril Duchon-Doris Points 4798

Il s'agit d'un exemple qui fonctionne sur le cloud AWS. Le scénario est le suivant : une machine qui a démarré à partir de l'autoscaling doit effectuer une action sur un autre serveur, en transmettant l'instance DNS nouvellement créée via SSH.

# Get the public DNS of the current machine (AWS specific)
MY_DNS=`curl -s http://169.254.169.254/latest/meta-data/public-hostname`

ssh \
    -o StrictHostKeyChecking=no \
    -i ~/.ssh/id_rsa \
    user@remotehost.example.com \
<< EOF
cd ~/
echo "Hey I was just SSHed by ${MY_DNS}"
run_other_commands
# Newline is important before final EOF!

EOF

10voto

muratgozel Points 549

J'utilise ce qui suit pour exécuter des commandes sur l'ordinateur distant depuis mon ordinateur local :

ssh -i ~/.ssh/$GIT_PRIVKEY user@$IP "bash -s" < localpath/script.sh $arg1 $arg2

6voto

Ted Bigham Points 1572

Je ravive un vieux fil, mais cette approche assez propre n'a pas été répertoriée.

function mycommand() {
    ssh user@123.456.789.0 <<+
    cd testdir;./test.sh "$1"
+
}

0voto

Mathieu Barbot Points 41

Un petit truc pour moi, en utilisant le "bash -s" ils ont dit qu'ils autorisent les ARGS POSITIONNELS mais apparemment le $0 est déjà réservé pour une raison quelconque... Ensuite, en utilisant deux fois les mêmes args, ça marche comme ça :

ssh user@host "bash -s" < ./start_app.sh -e test -e test -f docker-compose.services.yml

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X