2012-09-20 6 views
8

expectを使用して、単純なコマンドcat /tmp/id_rsa.pubをssh経由で実行したい。 (手動でパスワードを入れて)シェルで スペースを含む引数を持つコマンドを生成することを期待する

は、私が expectでこれを自動化したい

ssh [email protected] 'cat /tmp/id_rsa.pub' 

、これが問題めざし実行することができます。私expectスクリプトは、それがエラーbash: cat /tmp/id_rsa.pub: no such file or directoryをスローし、

#!/usr/bin/expect 
eval spawn ssh [email protected] 'cat /tmp/id_rsa.pub' 
expect "password:" 
send "123456" 
expect eof 

です。それは私には非常に奇妙に見えます。考えられる原因は何でしょうか?

編集:いくつかのテストの後、私はcatの場合だけでなく、これが一般的であることがわかります。 spawnedコマンドの引数がスペースであれば(引用符で囲まれていても)、問題があります。例えば、それはbash: which java: command not foundと文句を言い

eval spawn ssh [email protected] 'which java' 

のように、スペースで他のコマンドとcat /tmp/id_rsa.pubを交換します。しかし、それをpwdと置き換えると、

eval spawn ssh [email protected] 'pwd' 

のようになります。

+3

「コマンド引数」に関する一重引用符を削除しようとしましたか?問題の根本は、コマンドと引数に分割するのではなく、引用された文字列全体をコマンドの名前として解釈しようとしているようだ... – twalberg

+0

@twalberg that that working。私も二重引用符を試しました、wo/problem。好奇心のために、一重引用符について特別なことを少し説明できますか? – Richard

+0

私は、 'expect'ドキュメントを調べて、それが何を言うのかを知る必要があります - 私の頭の上から分かりません。私はあなたが得ていた特定のエラーメッセージの構文に基づいてそれを提案しました... – twalberg

答えて

0

私はそこにevalを必要としないと思います。それを取り出して確認してください。

expectの使用方法」の詳細については、expect examples linkをご確認ください。 。

これが役に立ちます。

+0

私は '' eval''なしで試しましたが、成功しませんでした。 – Richard

3

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

spawn ssh [email protected] 'cat /tmp/id_rsa.pub' 

は、次の単語に解析されることを意味します

  • spawn
  • ssh
  • [email protected]
  • 'cat - ではない他の単一引用符まで。
  • /tmp/id_rsa.pub'

SHでの使用は、単一の引数にグループこれです。 Tclでは二重引用符(")または中括弧({})を使用できます。二重引用符の中には、Tcl変数が代入され、{}の中の内容は、置換なしで渡されます。

t1; dr shの'の期待値/ Tclは{}です。

\改行がまだ置き換えられる前に。

2

Johannes氏によると、'を使用すると機能しません。
私も同様の問題がありましたが、より多くのコマンドを実行して、ログインシェルを取得したかったのです。 "

expect -c " 
    set timeout 5; 
    spawn ssh -XY [email protected]$host -t \"cat /etc/motd; bash -l\" 
    expect { 
     -re \"^Warning.*\" {exp_continue} 
     -re \"^.*sword: \" {send \"${PASSWORDS[$user]}\r\"; interact} 
    } 
" 
関連する問題