次のスクリプトを使用して、telnet 経由でルーターに接続しようとしています:
#!/usr/bin/expect -f
set timeout 20
# router user name
set name "admin"
# router password
set pass "admin"
# router IP address
set routerip "192.168.1.1"
# Read command as arg to this script
set routercmd "cat /var/1.leases"
# start telnet
spawn telnet $routerip
# send username & password
expect "username:"
send -- "$name\n"
expect "password:"
send -- "$pass\n"
# get out of ISP's Stupid menu program, go to shell
expect "TBS>>"
send -- "sh\n"
# execute command
expect -re ".*\$"
send -- "$routercmd\n"
# exit
send -- "^D"
これで、スクリプトは部分まで正常に動作しますsend -- "sh\n"
。シェル プロンプトが表示され、次のように表示されます: ~ $
(チルダ-スペース-ドル-スペース)。ただし、その後はコマンドを発行できません。基本的に、それ以降は動作しません。
理由を誰か教えてもらえますか? 私が何か間違いを犯しているのでしょうか?
答え1
expect
はい、解決しました。コードの最後の行の部分で、パターン マッチングが間違っていることが原因だったようです。
まず最初に、 を使用して記録されたスクリプトを生成しました。 このツールは、セッションを記録し、それに基づいてスクリプトを生成するために使用されます。 これを行うには、まずパッケージ (Debian ベースのシステムではパッケージで利用可能)autoexpect
をインストールし、次にセッションを記録しました。autoexpect
expect-dev
sudo apt-get install expect-dev #Since I'm on Ubuntu
autoexpect telnet 192.168.1.1
autoexpect
自動的にスクリプトを生成してくれました。このスクリプトを実行すると、コマンドの実行まで到達し、ルーターで実行しましたが、終了できませんでした。このスクリプトからヒントを得て、expect のマニュアル ページを読んで、パターン認識に問題があることがようやくわかりました。最終的にスクリプトをそれに応じて修正し、最終的に動作するようになりました。
#I am mentioning here only the end part of the complete script which was faulty
# execute command
expect "~ \$ "
send -- "$routercmd\r"
expect "~ \$ "
send -- "exit\r"
expect -- "TBS>>"
send -- "exit\r"
expect -- "*Are you sure to logout?*"
send -- "y"
expect eof
そこで学んだ教訓は、autoexpect
スクリプトを自動生成するために を使用する必要があるということです。そして、自動生成されたスクリプトに何らかの欠陥がある場合、その原因はおそらく、その部分のパターン認識が間違っていることにありますexpect
。
私の場合、本質的に欠陥があった部分は次のとおりです。
expect -re ".*\$" #WRONG
expect "~ \$ " #RIGHT
障害のある部分は、あなたが誰と連絡を取っているかというセッションによって完全に異なります。telnet 経由でメール サーバーに接続すると、異なる出力が返されるので、それに応じて対応する必要があります。