一部のSolarisマシンに自動的にログインし、hostnameコマンドを実行するために(expectに基づいて)active.kshスクリプトを記述します(どのホスト名がアクティブマシンであるかを確認するために仮想IPにログインします-2つのクラスタソラリスマシンがあります)
問題はexpect
にあります。 expectはパスワード文字列(pass123)を送信し、Passwordの質問を逃し、パスワードを待ちます。
したがって、実際にはパスワード(pass123)はパスワードの質問の後に入力されました。ほとんどの場合、expectスクリプトは正常に機能しますが、パスワードが欠落することもあります。
問題の例
./active.ksh
spawn ssh 10.10.18.61
sh: /usr/local/bin/stty: not found
This computer system, including all related equipment, networks and network devices (specifically including Internet access),is provided only for authorized uss
Password: * my remark - pass123 string was missed the Password Question pass123
Password:
#!/bin/ksh
VIP_ADDRESS=10.10.18.61
expect_for_verify_which_active_machine=`cat << EOF
set timeout -1
spawn ssh $VIP_ADDRESS
expect {
")?" { send "yes\r" ; exp_continue }
Password: {send "pass123\r"}
}
expect > {send "hostname\r"}
expect > {send exit\r}
expect eof
EOF`
expect -c "$expect_for_verify_which_active_machine"
./active.ksh
[Friday, February 24, 2012 2:32:06 PM IST] INFO Verify which is active SMU machine
spawn ssh 10.10.18.61
sh: /usr/local/bin/stty: not found
This computer system, including all related equipment, networks and network devices (specifically including Internet access),is provided only for authorized uss
yes
Password:
Last login: Fri Feb 24 14:32:06 2012 from smu1a
This computer system, including all related equipment, networks and network devices (specifically including Internet access),is provided only for authorized uss
solaris1:/ ROOT > hostname
solaris1
solaris1:/ ROOT > exit
logout
Connection to 10.10.18.61 closed.
ログイン時に文字列を監視する場合、「パスワード:」の使用は避けたいでしょう。大文字になっているとは限りません。
期待を-re "(.*)assword:"
または"assword:"
に変更すると、ラインをキャッチするのにはるかに効果的です。
それでもタイミングが速すぎる場合は、スリープ1にできます。送る前に
これは私が期待するものです
expect {
"(yes/no)?" { send "yes\n" }
"passphrase" { send "\r" }
-re "(.*)assword:" { sleep 1; send -- "password\r" }
-re $Prompt { return }
timeout { puts "un-able to login: timeout\n"; return }
eof { puts "Closed\n" ; return }
}
expect
を使用している理由がはっきりしません。リモートホストへのsshアクセスがあるので、最も簡単な解決策は、この目的のためにssh public key authentication を明示的に確立することです。その後、単に実行することができます...
ssh 10.10.18.61 hostname
...そしてすべてがうまくいく*。 expect
を使用していても、パスワード認証を使用しても上記のコマンドを発行でき、expectを使用してリモートシェルと対話することを心配する必要がないため、作業が多すぎます。あなたは次のようなものを送るでしょう:
#!/bin/sh
VIP_ADDRESS=10.10.18.61
expect <<EOF
spawn ssh $VIP_ADDRESS hostname
expect Password:
send "pass123\n"
expect eof
EOF
以上です。
-d
フラグを使用して、expectスクリプトをデバッグできます。私の場合、デバッグモードで実行された上記のexpectスクリプトの出力には、次のものが含まれます。
expect: does "" (spawn_id exp4) match glob pattern "password:"? no
lars@localhost's password:
expect: does "lars@localhost's password: " (spawn_id exp4) match glob pattern "password:"? yes
expect: set expect_out(0,string) "password:"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "lars@localhost's password:"
send: sending "PASSWORD\n" to { exp4 }
myhost.example.com
expect: read eof
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) " \r\nobliquity.int.seas.harvard.edu\r\n"
これは、expect
が何と一致し、何を送信しているかを正確に示します。
*技術的には、いくつかのホストキーの問題を解決する必要があるかもしれませんが、これは簡単です。