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_after
expect_before
lookfor
答え2
補完的なイカルスに役立つ回答、Expectスクリプトの先頭にこれを追加して、タイムアウト時に終了するようにすることができます。
expect_before {
timeout { puts "timeout"; exit 1 }
}
これはexpect
各コマンドの前に与えられたハンドラを付けます。タイムアウトが発生すると、「timeout」を印刷してから戻りコードで終了します1
。