Проблема заключается в том, что expect "$*"
.
Если вы хотите соответствовать буквальному знаку доллара ($
), то при использовании внутри двойных кавычек вы должны использовать следующий способ.
expect {\\\$}
Поскольку $
знак является особенным для обоих tcl
и expect
, для того, чтобы соответствовать буквальный знак доллара, мы должны избавиться от нее с обратной косой черты дважды, и, конечно, еще один символ, чтобы избежать самой обратной косой черты.
Есть еще 2 улучшений, которые можно сделать следующим образом,
Чтобы отправить «введите/возврат» ключ через expect
, мы рекомендуем использовать \r
, не \n
. (Хотя это не большая проблема в вашем вопросе. :))
Перед нерестом SSH сессии, вы перезаписью known_hosts
файл (> ~/.ssh/known_hosts
) и, таким образом, вы ожидаете для «(да/нет)», которые случаются только тогда, когда хост является новым для системы.
spawn ssh "$IP" -l root
expect "(yes/no)?
С помощью exp_continue
, мы можем справиться с такой же без перезаписи known_hosts. (Но, если удаление известных хостах каждый раз, когда это ваше реальное намерение, вам не нужно, чтобы добавить эту часть)
Объединив эти изменения в вашем сценарии, это будет походить следующим образом,
#!/bin/bash
if [ "$#" -eq 0 ]; then
IP="10.104.24.196"
else
IP="$1"
fi
PWD="something"
echo "Connecting to $IP with password:$PWD"
# I have commented this line, since I am using exp_continue.
# If you don't want, then keep your code as such
#> ~/.ssh/known_hosts
/usr/bin/expect -<< EOD
set timeout 60; # 1 min of timeout
spawn ssh "$IP" -l root
expect {
# you can keep your old code here if you want.
"(yes/no)" {send "yes\r";exp_continue}
"password"
}
send "$PWD\r"
expect {\\\$}
send "cd somewhere\r"
send "./db_deploy.sh\r"
expect "Script execution completed."
send "cd somewhere\r"
send "./apps_deploy.sh\r"
expect "Script execution completed."
send "exit\r"
expect eof
EOD
Вместо вложения ожидать сценарий непосредственно в сценарий Баш, вы можете сохранить файл отдельно и вызвать ожидать сценарий вроде как следует,
expect -c yourscript.exp
Посмотрите here знать об использовании двойных кавычек и одинарные кавычки при встраивании ожидание scri pt в сценарии bash.
Обновление: Насколько я беден, чтобы пропустить значение timeout
.
expect
Значение таймаута по умолчанию - 10 секунд. Это можно изменить, установив новое значение.
set timeout 60; # This value is in terms of seconds.
Установив тайм-аут до -1, мы делаем это ждать бесконечно. Вы использовали это значение. Попытайтесь изменить это на другое значение (например, 60 минут, равное 1 мин).
Возможно, в вашем случае, если $
не получил соответствия, он будет действовать как таковой. Если вы хотите обработать timeout
изящно, вы должны использовать следующее.
expect {
{\\\$} {puts "matched dollar sign"}
timeout { puts "timeout happened"}
}
Тем не менее это точно не отвечает на ваш вопрос. Можете ли вы попробовать expect
с флагом -d
и делиться результатами в своем вопросе? Чтобы мы могли вам помочь.
с ожиданием {\\\ $} он останавливается там всегда с параметрами командной строки или без них! – Shamik
И я не понял, как прохождение аргумента повлияло на оболочку ожидания. Мой код работает, когда аргумент не передается. – Shamik
@raynaya: К сожалению. Виноват. Только что нашел проблему. См. Обновленный ответ. :) – Dinesh