web-dev-qa-db-fra.com

utiliser la commande Spawn avec des arguments contenant des espaces

Je souhaite utiliser expect pour exécuter une commande simple cat /tmp/id_rsa.pub sur ssh.

Dans un shell, je peux exécuter ce problème (avec la saisie manuelle du mot de passe)

ssh root@localhost 'cat /tmp/id_rsa.pub'

Je veux automatiser ceci avec expect. Mon script expect est,

#!/usr/bin/expect
eval spawn ssh root@localhost 'cat /tmp/id_rsa.pub'
expect "password:"
send "123456"
expect eof

Il génère une erreur bash: cat /tmp/id_rsa.pub: no such file or directory. cela me semble très étrange. Quelle pourrait être la cause possible?

Edit: après quelques tests, je trouve que c'est courant, pas seulement dans le cas de cat. Si l'argument de la commande spawned est avec espace (même s'il est entre guillemets), il y aura un problème. Par exemple, remplacer cat /tmp/id_rsa.pub par d'autres commandes avec des espaces, comme 

eval spawn ssh root@localhost 'which Java'

il se plaint avec bash: which Java: command not found. Mais si cela remplace par pwd, comme 

eval spawn ssh root@localhost 'pwd'

ça marche bien.

9
Richard

Les guillemets simples (') n'ont pas de signification particulière pour Expect, contrairement à sh et aux autres coques compatibles.
Cela signifie que votre déclaration

spawn ssh root@localhost 'cat /tmp/id_rsa.pub'

est analysé dans les mots suivants:

  • spawn
  • ssh
  • root@localhost
  • 'cat - pas jusqu'à l'autre citation simple.
  • /tmp/id_rsa.pub'

L'utilisation dans sh consiste à grouper cela en un seul argument. En Tcl, vous pouvez utiliser des guillemets (") ou des accolades ({}). Dans les guillemets doubles, les variables Tcl seront substituées, tandis que le contenu à l'intérieur de {} est passé sans substitution1.

tl; dr L'équivalent Expect/Tcl du ' de sh est {}.

1 Un \ avant une nouvelle ligne sera toujours substitué.

3
Johannes Kuhn

Comme Johannes l'a dit, utiliser ' ne fonctionne pas.
J'ai eu un problème similaire, mais je voulais exécuter plus de commandes et toujours obtenir un shell de connexion. J'ai réussi à le faire fonctionner avec ":

expect -c "
   set timeout 5;
   spawn ssh -XY $user@$Host -t \"cat /etc/motd; bash -l\"
   expect {
      -re \"^Warning.*\" {exp_continue}
      -re \"^.*sword: \" {send \"${PASSWORDS[$user]}\r\"; interact}
   }
"
3
genesys87

Je suppose que vous n'avez pas besoin de eval. Retirez-le et vérifiez.

Cochez cette case attendons des exemples de lien pour des exemples détaillés sur "comment utiliser expect?" .

J'espère que cela t'aides.

0
mtk