0

私は次のexpectスクリプトを持っています:

  • ホストへのSSH
  • 必要に応じてユーザーからのパスワードを受け入れる
  • sshが成功したら(プロンプトが表示されます)、環境変数を設定します
  • プロンプトに戻ったら、ネットワークテスト用のプログラムを実行します
  • プロンプトに戻ったら、expectを終了し、sshセッションを閉じます
#!/usr/bin/expect
set hostname [lindex $argv 0]
set working_dir [lindex $argv 1]
set package [lindex $argv 2]
set tcl_test $working_dir/$package.tcl
set config $working_dir/$package.config
set logdir $working_dir/$package
set timeout 30
set prompt "\~\\\]\\\$"

eval spawn ssh $hostname
expect {
    -re "(yes/no)" {send "yes\r"}
    -re "password\:" {      
        interact {
            -o
            -re $prompt {send "export VARIABLE1=$working_dir\"\r"}
            -re $prompt {send "issue-test-command -config $config -module $tcl_test\r"}
        }
    }
}

パスワードの一致と相互作用は正しく機能します。$ promptが一致するとすぐに、環境変数exportコマンドが発行されます。

-re $prompt {send "export VARIABLE1=$working_dir\"\r"}

これは正しいですが、次の行に進むのではなく、次のようにします。

-re $prompt {send "issue-test-command -config $config -module $tcl_test\r"}

同じ行が読み取られ、パターンが再度照合され、同じコマンドが実行されます。これにより、同じコマンドを発行する永続的なループが発生します。

インタラクションを強制して次の行に移動したり、別の期待値ビルトインを使用して目的を達成するにはどうすればよいですか?

4

2 に答える 2

2

あなたが誰かに指示を与えていると想像してください:

  1. 赤信号が表示されたら停止します
  2. 赤信号が表示された場合は、

彼らが混乱しても驚かないでしょう。-re $promptそれはあなたが複数のブランチで期待するためにやっていることです。ただし、Expectは、最初に指示した指示を受け取ります。

これを試して:

    interact {
        -o
        -re $prompt {
            send "export VARIABLE1=\"$working_dir\"\r"
            send "issue-test-command -config $config -module $tcl_test\r"
        }
    }

ところで:

  1. あなたはexp_continue後に行方不明ですsend "yes\r"
  2. exportコマンドで間違った数の二重引用符を送信しています
于 2012-09-24T08:18:32.757 に答える
1

同じパターンを複数回指定すると、関連するアームの1つだけが実行されます。より複雑なものは完全に書き出す必要があります(たとえば、小さなステートマシンを使用して)。

しかし、あなたはそのコードをかなり複雑にしすぎていると思います。あなたが本当に望んでいる唯一の場所interactは、プログラムを開始した後です。マルチアームが必要になる可能性がある唯一の場所はexpect、インタラクションのその時点で発生する可能性のある複数のことがある場合です。もっと簡単に書いてみましょう。ただし、を使用しexp_continueます。(変数の設定は省略しています…)

eval spawn ssh $hostname
# Manage the login sequence, with its optional host check and optional password
# (that's optional in case someone decides to properly set up RSA keys)
expect {
    -ex "(yes/no)" {      # Exact match here
        send "yes\r"
        exp_continue
    }
    -ex "password:" {     # Exact match here
        send "$password\r"
        exp_continue
    }
    -re $prompt {         # RE match here
        # Do nothing; fall out of the expect as we're now logged in...
    }
}

# We're now at a prompt; make things work as desired
send "export VARIABLE1=\"$working_dir\"\r"
expect -re $prompt
send "issue-test-command -config $config -module $tcl_test\r"

# Now we're ready to let the user talk to the program...
interact
于 2012-09-24T10:24:47.963 に答える