Expectスクリプトの終了

Expectスクリプトの終了

expectホストにログインし、コマンドを実行し、内容を返して終了するスクリプトがあります。コマンドの実行後、どのようなクリーンアップ/適切なシャットダウンが必要ですか?このコマンドは常に何かを返し、私が処理する必要があるより大きな問題はSSHの中断または管理者ユーザーとしてログインを中断したと思います。私の考えでは、この問題は次のように処理された可能性がありますtimeout

#!/usr/bin/expect -f

set timeout 10
match_max 100000
set hostname [lindex $argv 0]

spawn /usr/bin/ssh -o "StrictHostKeyChecking no" admin@$hostname
expect "*password:"
send -- "redactedSSHpassword\r"
expect "Username:"
send -- "admin\r"
expect "*password:"
send -- "redacted\r"
expect -- "*#*"
send -- "show stat summary\r"
expect -- "*#*"

また、このスクリプトを終了し、古いセッションを残さない正しい方法を理解していません。

答え1

タイムアウトすると、expect文は失敗し、次の文を続行します。これは言葉にならないかもしれませんが、次のことが起こる可能性があることを意味します。

You expect "Username:" and get it.
You send "admin\r", and get back "No such username"
You expect "password:" but don't get it because you got the "No such username" message, so you timeout.
You send "redacted\r" and get back "redacted: no such command" but redacted has been added to the history on the machine.
You expect "*#*" ....

スクリプトが最後に到達すると終了します。この時点で、sshはPID 1にリセットされます。 sshは標準入力でEOFを検出し、それを渡して終了します。したがって、追加のクリーンアップが必要ない場合があります。

これが私のスクリプトなら、私は小さなプログラムを書くでしょう

proc lookfor {pat} {
    expect timeout { send_user "timeout looking for '$pat'\r\n" ; exit } $pat
}

一致が失敗した場合はすぐに終了するようにすべての呼び出しをexpect置き換えます。簡単な診断には、またはをlookfor使用できます。expect_afterexpect_beforelookfor

答え2

補完的なイカルスに役立つ回答、Expectスクリプトの先頭にこれを追加して、タイムアウト時に終了するようにすることができます。

expect_before {
    timeout { puts "timeout"; exit 1 }
}

これはexpect各コマンドの前に与えられたハンドラを付けます。タイムアウトが発生すると、「timeout」を印刷してから戻りコードで終了します1

関連情報