15

ssh経由expectで簡単なコマンドを実行するために使用したい。cat /tmp/id_rsa.pub

シェルでは、この問題を実行できます (手動でパスワードを入力して)

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

でこれを自動化したいexpect。私のexpectスクリプトは、

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

エラーがスローされますbash: cat /tmp/id_rsa.pub: no such file or directory。私にはとても奇妙に見えます。考えられる原因は何ですか?

編集:いくつかのテストの後、これは の場合だけでなく、一般的であることがわかりましたcat。生成されたコマンドの引数にスペースが含まれている場合 (引用符で囲まれている場合でも)、問題が発生します。たとえば、次cat /tmp/id_rsa.pubのようなスペースを含む他のコマンドに置き換える

eval spawn ssh root@localhost 'which java'

と文句を言いbash: which java: command not foundます。しかし、それを に置き換えるとpwd

eval spawn ssh root@localhost 'pwd'

それはうまくいきます。

4

3 に答える 3

8

一重引用符 ( ') は、sh やその他の互換シェルとは異なり、Expect にとって特別な意味を持ちません。
これは、あなたの声明が

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

次の単語に解析されます。

  • spawn
  • ssh
  • root@localhost
  • 'cat- 他の一重引用符まで。
  • /tmp/id_rsa.pub'

sh での使用法は、これを単一の引数にグループ化することです。"Tcl では、二重引用符 ( ) または中括弧 ( )を使用できます{}。二重引用符内では、Tcl 変数が置換されますが、内部のコンテンツ{}は置換なしで渡されます1

tl;dr sh に相当する Expect/Tcl'は are{}です。

改行の前の1 A\は引き続き置換されます。

于 2013-10-16T12:02:44.067 に答える
5

ヨハネスが言ったように、使用'は機能しません。
同様の問題がありましたが、さらにコマンドを実行してからログインシェルを取得したかったのです。私はそれをうまく動作させることができました":

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}
   }
"
于 2014-03-05T10:33:19.857 に答える
0

そこは必要ないと思いますeval。外して確認。

「使用方法」に関する詳細な例については、この予期される例のリンクexpectを確認してください。.

お役に立てれば。

于 2012-09-20T18:14:55.757 に答える