8

私はsshでパスワードを自動的に入力するという古典的な問題に苦しんでおり、他のみんなと同じように、私は期待に関して暗闇の中でつまずいています。最後に、私はちょっとうまくいくスクリプトをまとめました:

#!/usr/bin/expect -f

# command line args
set user_at_host [lrange $argv 0 0]
set password [lrange $argv 1 1]

set timeout 1

# ssh command
spawn ssh -S ~/.ssh/tmp.$user_at_host -M -N -f $user_at_host

# deal with ssh prompts
expect {
    "*yes/no*" { send "yes\r" ; exp_continue }
    "*assword:" { send "$password\r" ; exp_continue }
}

このスクリプトは、行のおかげで終了します。timeout 1行がないと、単にハングし、ユーザーの操作()によってのみ終了します^C

行が単純なsshコマンドの場合spawn、スクリプトはすぐに終了しましたが、これは単純なsshではありません。異なる可能性があるのは-f、バックグラウンドで実行するオプションです(ただし、スクリプトを使用せずに試してみましたが、役に立ちませんでした)。

私はそれを読んだinteractexpect eof、役立つかもしれませんが、実際にそれを行う正しい呪文を見つけることができませんでした。

私の質問(私は思う)は、バックグラウンドプロセスを生成するexpectスクリプトを、タイムアウトなしで終了させる方法ですか?


編集:「パスワードなしのssh認証を使用する」という答えを期待する必要がありました(しゃれは意図していません)。これは適切なアドバイスですが、私のシナリオでは適切な解決策ではありません。信頼できる環境でバニラがインストールされたシステムを自動テストします。信頼できるキーをイメージに追加することは望ましくない/不可能です。

4

4 に答える 4

7

あなたはおそらく欲しい:

expect {
    "*yes/no*" { send "yes\r" ; exp_continue }
    "*assword:" { send "${password}\r" }
}
expect $the_prompt
send "exit\r"
expect eof

アップデート

ssh経由でコマンドを送信しているのを見逃しました。必要なのはこれだけだと思います。

spawn ssh a@b foo bar baz
expect {
    "*yes/no*" { send "yes\r" ; exp_continue }
    "*assword:" { send "${password}\r" }
    eof
}

コマンドが完了するとヒットeofします。foo

于 2010-06-30T01:30:48.807 に答える
2

よし、うまくいきそうな順列を見つけた -

まずwrapper、完了時に指示を出すスクリプトが必要です。

#!/bin/bash
"$@"
echo "done"

次に、expect スクリプトは次のようになります。

#!/usr/bin/expect -f
set user_at_host [lrange $argv 0 0]
set password [lrange $argv 1 1]

# no need for timeout 1
set timeout 60

# use the wrapper
spawn wrapper ssh -S ~/.ssh/tmp.$user_at_host -M -N -f $user_at_host

expect {
   "*yes/no*" { send "yes\r" ; exp_continue }
   "*assword:" { send "$password\r" ; exp_continue }
   # use the wrapper
   "done" { exit }
}

役に立つアドバイスをくれたDouglas Leeder (賛成票) とglenn jackman (賛成票) に感謝します。私は喜んでこの回答を受け入れず、より洗練された回答、おそらくラッパースクリプトを廃止するものを受け入れます。

ご清聴ありがとうございました。

于 2010-06-30T06:19:03.560 に答える
1

このループ:

expect {
    "*yes/no*" { send "yes\r" ; exp_continue }
    "*assword:" { send "${password}\r" ; exp_continue }
}

タイムアウトまたは EOF 以外の方法で終了することはできません。2 つの一致する行はexp_continueになるので、ループをもう一度丸めます。

バックグラウンドに入るということは、基本的にフォークすることを意味します。親が死亡し、子が接続を継続します。

個人的には、インタラクティブな要素を別の方法で解決します。

  1. ホスト キー: 手動で 1 回接続するか、キーを ssh known_hosts ファイルに直接挿入します。
  2. パスワード: 秘密鍵/公開鍵認証を使用します。エージェントを使用して鍵を保管するか、パスワードのない鍵を用意してください。
于 2010-06-29T14:07:19.777 に答える