2015-10-08 3 views
1

Я пытаюсь создать скрипт, который входит в систему через ssh, но чтобы сделать его более сложным, я должен ssh на один сервер, а затем ssh в другой, чтобы добраться до сервера, который я хочу быть на. Код, который я до сих пор прекрасно работал, чтобы получить меня на первый сервер, но не работает, когда он затем пытается ssh в следующий.2-ступенчатый вход через ssh, используя ожидание

#! /usr/bin/expect -f 

# set servers to ssh into 
set server1 "foo" 
set server2 "bar" 

# get username 
send_user -- "Enter username: " 
expect_user -re "(.*)\n" 
set user $expect_out(1,string) 

# get password 
# don't ouput password to the user 
stty -echo 
send_user -- "Enter password for \"$user\": " 
expect_user -re "(.*)\n" 
send_user "\n" 
stty echo 
set password $expect_out(1,string) 

# start the login 
spawn ssh [email protected]$server1 
expect "assword:" 
send -- "$password\r" 

# problems happen after here 

# required to ssh from the <something> into <something else> 
# the host name varies, e.g. host1, host2, host3, etc. 
# so this just detects the last character 
expect -re "\$ $" 
send -- "ssh [email protected]$server2\r" 
# sometimes it outputs this, sometimes it doesn't 
expect "(yes/no)?" 
send -- "yes\r" 
expect "assword:" 
send -- "$password\r" 

interact 

Это то же имя пользователя и пароль для обоих серверов.

ответ

1

Вы сделали ошибку в

expect -re "\$ $"; # WRONG 

Если вы хотите, чтобы соответствовать буквальный знак доллара вместе с концом строки, вы должны использовать

expect -re "\\\$ $"; # CORRECT 

который будет соответствовать буквальный знак доллара и пробел на конце линии.

В качестве альтернативы, чтобы соответствовать какому-то общеизвестному приглашению, вы можете определить переменный как

set prompt "#|>|%|\\\$ $"; # We escaped the `$` symbol with backslash to match literal '$' 

Последний знак доллара представляет конец строки.

В то время как используется expect, мы должны сопровождать флаг -re, чтобы указать его как регулярное выражение.

expect -re $prompt 

Если мы не знаем, будет ли конкретное слово прибыть в выходной или если мы не уверены в порядке их появления, то рекомендуется использовать exp_continue.

send -- "ssh [email protected]$server2\r" 
# sometimes it outputs this, sometimes it doesn't 
expect { 
     "(yes/no)?" {send -- "yes\r";exp_continue} 
     "ssword:" {send -- "$password\r"} 
} 
expect -re $prompt 
+1

Хороший ответ. Для регулярного выражения я обычно использую разные кавычки: 'ожидать -re {\ $ $}' –