0

私はどのように働くことを期待するかを理解しようとしています。私の知る限り、expect スクリプトは「expect」ステートメントと「send」ステートメントで構成されています。したがって、画面に表示される適切な「expect」ステートメントごとに、「send」ステートメントが呼び出されます。また、コマンド「interact」は、制御がユーザーに返され、ユーザーが端末と対話できることを意味します。私が間違っている場合は修正してください。これらの 2 つのステートメントは魅力のように機能します。

1位:

#!/usr/bin/expect
spawn ssh -q localhost;

# Handles following message: "Are you sure you want to continue connecting (yes/no)?"
expect "yes";
send "yes\r";
interact;

2番目:

#!/usr/bin/expect
spawn ssh -q localhost;

# Handles following message: "pista@localhost's password:" 
expect "assword";
send "password\r";
interact;

インターネットで、次のコードのようなものがこれら2つの例を1つに結合する必要があることを発見しました:

#!/usr/bin/expect
spawn ssh -q localhost "uname -a";
expect {
    "*yes/no*" { send "yes\r" ; exp_continue }
    "*assword:" { send "password\r"; interact }
}

ただし、この例では、完全なログインに成功するとすぐに終了します (ここでは「対話」が機能していないようです。以下の出力を参照してください)。

[pista@HP-PC .ssh]$ ./fin.exp
spawn ssh -q localhost uname -a
pista@localhost's password: 
Linux HP-PC 3.6.6-1.fc16.x86_64 #1 SMP Mon Nov 5 16:56:43 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
[pista@HP-PC .ssh]$ set | grep SHLV
SHLVL=2

3 つの質問:

  1. これらの奇妙な期待構文の意味は、この「大きな」期待ではパターンの順序に重点が置かれていないということだけです。
  2. exp_continue が正確に何をしているのかを明確にしていただけますか?
  3. ここで対話が機能しないのはなぜですか?

どうもありがとう

4

1 に答える 1

1

1.この構文は、expect ステートメントを連続して使用することを意味します。より簡単です。たとえば、SSH が失敗した場合、これは SSH または telnet を試行します

#!/usr/bin/expect
set remote_server [lrange $argv 0 0]
set timeout 10
spawn ssh -M username@$remote_server
while 1 {
  expect {
    "no)?"      {send "yes\r"}
    "denied" {
                log_file /var/log/expect_msg.log
                send_log "Can't login to $remote_server. Check username and password\n";
                exit 1
             }
    "telnet:" {
                log_file /var/log/expect_msg.log
                send_log "Can't connect to $remote_server via SSH or Telnet. Something went definitely wrong\n";
                exit 2
              }
    "failed" {
                log_file /var/log/expect_msg.log
                send_log "Host $remote_server exists. Check ssh_hosts file\n";
                exit 3
             }
    timeout {
                log_file /var/log/expect_msg.log
                send_log "Timeout problem. Host $remote_server doesn't respond\n";
                exit 4
            }
    "refused" {
                log_file /var/log/expect_msg.log
                send_log "Host $remote_server refused to SSH. That is insecure.\n"
                log_file
                spawn telnet $remote_server
              }
    "sername:" {send "username\r"}
    "assword:" {send "password\r"}
    "#"        {break}
  }
}

2. exp_continue は、「引き続き期待する」、つまりイベント処理を続行することを期待しています。この指示がないと、expect { ... } ブロックが停止します。上記の例では、次の行です。

"#" {break}

最初に while ループから抜け出し、次に exp_continue がない場合、expect { ... } ブロックの実行を停止し、次の命令に進みます (上記の例には示されていません)。

3.コードにエラーがあります。動作するように、コードを少し変更しました。

#!/usr/bin/expect
spawn ssh -q localhost
expect {
    "*yes/no*" { send "yes\r" ; exp_continue }
    "*assword:" { send "password\r"; exp_continue;}
    "~" {send "uname -a\r"; interact;}
}
于 2012-12-26T12:26:20.243 に答える