expect
を使用して、ssh経由で単純なコマンドcat /tmp/id_rsa.pub
を実行したいと思います。
シェルでは、この2つの問題を実行できます(手動でパスワードを入力します)
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'
それはうまくいきます。
単一引用符('
)は、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は{}
です。
1 改行の前の\
は引き続き置換されます。
ヨハネスが言ったように、'
が機能しません。
同様の問題が発生しましたが、さらにコマンドを実行して、ログインシェルを取得したかったのです。 "
:
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}
}
"