私は次のスクリプトを作成しました。
#!/usr/bin/expect -f
set ip [lindex $argv 0];
spawn ssh name@server
expect "assword"
set timeout 0.5
send "password\r"
expect "xxxxx"
set timeout 1
send "telnet $ip\r"
expect "assword"
send "password\r"
expect "xxxxxx"
send "xxxxxxx\r"
.
.
.
.
スクリプトは、私の出力が次のように表示される位置まで続きます。
Last update from 1.1.1.1 1d06h ago
Routing Descriptor Blocks:
* 1.1.1.1 from 2.2.2.2
1.1.1.1
続行できるように、常に一意のIP()を抽出して自動的にスクリプトに渡す方法を理解する必要があります。
答え1
2つのインスタンスがあります1.1.1.1
。最初のインスタンスが一致する可能性があると仮定すると、最初に目的の出力を生成する簡単なスクリプトを作成し、リモートデバイスでほとんど実行される誤ったプロンプトも含める必要があります。
#!/usr/bin/env expect
proc prompt {} { puts "prompt"; gets stdin; }
prompt
puts "Last update from 1.1.1.1 1d06h ago"
puts " Routing Descriptor Blocks:"
puts " * 1.1.1.1 from 2.2.2.2"
prompt
このスクリプトを呼び出しgenerator
てから、そのスクリプトを呼び出して対話するには、別のスクリプトが必要です。しかし、まず、他の端末でこれらのスクリプトの変更をすばやく繰り返す方法を見てみましょう。
$ (echo consume; echo generate) | entr ./consume
...
consume
consume
スクリプトが変更されるたびにスクリプトを実行しますgenerate
。その後、スクリプトを操作してプロンプトと対話し、目的の出力を見つけて正規表現を適用できます(マニュアルを読むregexp(n)
)。
#!/usr/bin/env expect
spawn -noecho ./generate
expect -ex prompt
send -- "before\r"
expect -ex prompt
# this is what I used to confirm that the required prompt block
# had been matched
#puts ">>>$expect_out(buffer)<<<"
regexp {Last update from ([^ ]+) } $expect_out(buffer) unused theip
puts ">>>$theip<<<"
send -- "after\r"
expect eof
この方法は、所望の出力がヒントによってサポートされると仮定する。別のオプションは正規expect
表現行を使用することですが、Last update ...
これはより複雑になる可能性があります。さらに、このIPアドレスの一致は、ほぼすべてのエントリと一致する可能性があります。テキストが実際にIPアドレスであることを確認する必要がある場合は、より正確な正規表現を使用してください。
その他の問題:
- タイムアウトは非常に短いです。関連するシステムまたはネットワークが遅く、出力が指定されたタイムアウトより長くかかる場合はどうなりますか?
ssh
システムでホストキーエラーまたはプロンプトが発生した場合、エラーチェックはあまりありません。