Скрипт Expect, работавший годами, неожиданно ведет себя с новой версией Expect

Недавно я перешел с сервера FreeBSD 4.x на сервер FreeBSD 8.0. Сейчас я использую expect-5.43.0_3. Я не помню, что такое старая версия expect, и не могу быстро проверить, потому что жесткий диск в старой системе вышел из строя через несколько минут после завершения миграции! (ВАУ!)

Во всяком случае, у меня есть ожидаемый скрипт, который создает заархивированный tar-файл и каждую ночь передает его по FTP. Этот сценарий успешно работает уже ГОДЫ. Внезапно, после миграции/обновления, он работает неправильно, и я смотрел на него и возился с ним в течение ДНЕЙ, не имея возможности это исправить. Я хочу убедиться, что каждая FTP-команда выполнена успешно, прежде чем переходить к следующей, потому что следующие шаги включают удаление выбранных старых версий файла на удаленном сервере, и я не хочу выполнять УДАЛЕНИЯ, если ПЕРЕДАЧИ не работает правильно.

Итак - эта часть скрипта все еще работает:

...

spawn ftp $ftpmode $ftphost
expect timeout {puts "\nftp connection timeout(implicit)\n"; exit 3}
"timed out" {puts "\nftp connection timeout(explicit)\n"; exit 3} 530 {puts "Login failure!"; exit 3 } "\n230"
expect timeout {puts "\nftp command prompt timeout before progress command\n"; exit 8} "ftp> "
send "progress off\r"
expect timeout {puts "\nftp command prompt timeout before hash command \n"; exit 9} "ftp> "
send "hash 32768\r"
expect timeout {puts "\nftp command timeout";exit 5} "ftp> "

# For each archive file we find (this will catch us up if we've
# been unable to transmit for a few days), send and delete
foreach archive [glob -nocomplain ${archivestem}*$archiveext] {
    send "put $archive\r"
    expect "ftp> " {puts "ftp unexpected prompt 1"; exit 3} timeout {puts "ftp put timeout\n";exit 3} "\n150"

... Вот поток диалога, который соответствует выполнению вышеизложенного:

230 User XXXXXXX logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> progress off
Progress bar off.
ftp> hash 32768
Hash mark printing on (32768 bytes/hash mark).
ftp> put crewsched-alldump-2010-02-27.tgz
local: crewsched-alldump-2010-02-27.tgz remote: crewsched-
alldump-2010-02-27.tgz
227 Entering Passive Mode (141,224,159,31,30,167)
150 Opening BINARY mode data connection for .
#####################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################
226 Transfer complete.
21689518 bytes sent in 01:15 (280.27 KB/s)

(Примечание: хеш-метки позволяют мне использовать низкое значение тайм-аута и быстро определить, завис ли скрипт)

Все идет нормально! Все по-прежнему работает так же, как и последние ШЕСТЬ ЛЕТ, но следующая строка завершается с ошибкой «ftp неожиданное приглашение 2», хотя искомая строка «\ n226» ЯВНО находится в потоке диалога.

    expect \# exp_continue "ftp> " {puts "ftp unexpected prompt 2"; exit 3} timeout {puts "ftp put timeout\n";exit 3} "\n226"

Обратите внимание, что в диалоговом потоке было ЯВНО «\n226» ПЕРЕД «ftp>», но я постоянно получаю «неожиданное приглашение ftp 2». Я попытался изменить его на «Перевод» или «Завершить», но это все равно имело тот же эффект. Прямо сейчас я запускаю скрипт БЕЗ проверки на успешное завершение, но, очевидно, меня это не устраивает, и это ожидание несчастного случая, так как следующие шаги удаляют выбранные старые файлы, чего я не хочу делать. если эти файлы не были успешно переданы, какого теста у меня в настоящее время НЕТ.

Я предполагаю, что что-то изменилось с буферизацией/обработкой входного потока, и что мне нужно изменить это так, чтобы он «видел» «\ n226» или «Передача» или «завершение» до того, как он «увидит» строку «ftp>». , но почему? И, если уж на то пошло, как? :)


person John    schedule 03.03.2010    source источник
comment
Вместо того, чтобы использовать сложный сценарий ожидания, просто используйте команду ncftpput из пакета ncftp. Он позволяет вам поместить файл на ftp-сервер аналогично scp и возвращает ненулевое значение в случае ошибки.   -  person a'r    schedule 03.03.2010
comment
Принадлежит superuser.com   -  person t0mm13b    schedule 03.03.2010
comment
Вы запускали его с exp_internal 1? Затем вы можете увидеть входной поток так, как его видит ожидаемое.   -  person glenn jackman    schedule 03.03.2010


Ответы (1)


Это может быть проблема с буферизацией, и изменение порядка элементов в операторе ожидания может помочь.

Помните, что по умолчанию вы указываете шаблоны "glob" и что эти шаблоны сравниваются с буферами данных внутри Expect, а не строго посимвольно. Предположим, что в буфере оказался этот фрагмент входного потока:

######
226 Transfer complete.
21689518 bytes sent in 01:15 (280.27 KB/s)
ftp>

Это соответствует как шаблону glob "ftp>", так и шаблону "\n226", и, поскольку первый появляется первым в операторе ожидания, это действие будет выполнено.

person eemz    schedule 01.04.2010