Я пишу сценарий active.ksh (на основе ожидаемого), чтобы автоматически войти в систему на некоторой машине Solaris и выполнить команду hostname (войти в виртуальный IP-адрес, чтобы проверить, какое имя хоста является активной машиной - у меня есть две машины Solaris кластера)
Проблема с expect
; expect отправляет строку пароля (pass123), пропускает вопрос о пароле и все еще ждет пароля.
Фактически, пароль (pass123) был введен после вопроса о пароле. В большинстве случаев сценарий ожидания работает нормально, но иногда он пропускает пароль.
ПРИМЕР ПРОБЛЕМЫ
./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 аутентификация с открытым ключом специально для этой цели; тогда вы могли бы просто бежать ...
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: 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
совпадает и что отправляет.
* Технически вам, возможно, придется решить некоторые ключевые проблемы хоста, но это легко.