ожидайте: получить статус ошибки, когда команда создания процесса завершается неудачей

Вопрос или проблема

Ниже представлен образец скрипта, который мы выполняем ежедневно для получения информации с сервера. В последние несколько дней некоторые данные сервера отсутствуют в выходных данных, которые сохраняются в локальном файле VS-HV-Report_2017.txt.

Возможно ли получить статус ошибки при выполнении скрипта, если он не может подключиться к серверу? Чтобы у нас была черная строка или статус ошибки вместо выходных данных?

#!/usr/bin/expect
set timeout 5
#find /path/to/files -type f -mtime +10 -delete
set date [exec date "+%d-%B-%Y"]

spawn sh -c "yes | cp -ifr .ssh/VS-HV-config .ssh/config"

spawn sh -c "> VS-HV-Report_2017.txt"

#cat ./info.py 
spawn sh -c "ssh L1n \"./info.py | sed 's/total.*//g'\" >> VS-HV-Report_2017.txt"
expect "Enter passphrase for key '/root/.ssh/id_rsa':"
send "passwd\r"

spawn sh -c "ssh L2n \"./info.py | sed 's/total.*//g'\" >> VS-HV-Report_2017.txt"
expect "Enter passphrase for key '/root/.ssh/id_rsa':"
send "passwd\r"

spawn sh -c "ssh L3n \"./info.py | sed 's/total.*//g'\" >> VS-HV-Report_2017.txt"
expect "Enter passphrase for key '/root/.ssh/id_rsa':"
send "passwd\r"
set timeout 5

#spawn sh -c "./format-VS-HV.sh > format-allinement-output.csv"
#spawn sh -c \"./format-VS-HV.sh\" > format-allinement-output.csv
exec ./format-VS-HV.sh > /root/format-allinement-output/format-allinement-output-$date.csv

Ваш код представляет собой любопытную смесь TCL и оболочки и, вероятно, должен быть написан только на одном из них. С TCL он мог бы выглядеть примерно так:

#!/usr/bin/expect

set timeout 5

# TCL имеет функции времени, нет необходимости вызывать `date`...
set epoch    [clock seconds]
set outfile  "VS-HV-Report_[clock format $epoch -format "%Y"].txt"
set date     [clock format $epoch -format "%d-%B-%Y"]

# "yes | cp -i ..." очень странно; зачем интерактивный флаг, а затем
# игнорировать его с помощью "yes |" из неинтерактивного кода?
#spawn sh -c "yes | cp -ifr .ssh/VS-HV-config .ssh/config"
exec cp -f .ssh/VS-HV-config .ssh/config

# TCL может выполнять I/O, давайте используем это вместо разветвления процессов sh...
#spawn sh -c "> VS-HV-Report_2017.txt"
set outfh [open $outfile w+]

# и цикл TCL вместо дублирования кода запуска для хоста...
set hostlist {L1n L2n L3n}
foreach host $hostlist {
    set done_auth 0

    # Запуск sh для запуска ssh довольно сложен; давайте просто
    # вызовем ssh напрямую (и поймаем любые ошибки...)
    #spawn sh -c "ssh L1n \"./info.py | sed 's/total.*//g'\" >> VS-HV-Report_2017.txt"
    if { [catch {spawn ssh $host {./info.py | sed 's/total.*//g'}} msg] } {
        puts $outfh "SSHFAIL $host $msg"
        continue
    }

    while 1 {
        expect {
            -re {Enter passphrase for key '[^']+': } {
                # поскольку в цикле (потому что EOF или таймаут могут произойти
                # в любом месте) нужно аутентифицироваться только один раз в том случае, если удаленная
                # сторона не ведет себя хорошо
                if {$done_auth == 0} {
                    send "hasapass\r"
                    set done_auth 1
                }
            }
            # помните ли вы о таймауте? для него есть хук.
            timeout {
                puts $outfh "TIMEOUT $host $timeout"
                break
            }
            # выведите любые "данные сервера", возвращенные в выходной
            # файл (match_max может быть актуален при чтении, если есть
            # много данных) когда соединение закрывается
            eof {
                puts $outfh $expect_out(buffer)
                break
            }
        }
    }
}

close $outfh

exec ./format-VS-HV.sh > /root/format-allinement-output/format-allinement-output-$date.csv

Ответ или решение

В качестве эксперта в области информационных технологий, я хотел бы обсудить, как можно обрабатывать ошибки и получать статус выполнения при использовании скриптов на языке Expect, особенно в ситуациях, когда необходимо иметь возможность установить, выполнена ли команда подключения к серверу успешно. Рассмотрим модификацию вашего скрипта, чтобы обеспечить обработку ошибок в случае недоступности сервера.

Задача

В вашем оригинальном скрипте используется команда spawn для подключения к нескольким серверам и выполнения скрипта info.py. Однако в случае, если соединение с сервером не удается установить, необходимо добавить функционал для записи ошибки в выходной файл и отображения информации о неудачном подключении.

Обработка ошибок

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

#!/usr/bin/expect

set timeout 5
set epoch [clock seconds]
set outfile "VS-HV-Report_[clock format $epoch -format "%Y"].txt"
set date [clock format $epoch -format "%d-%B-%Y"]
set outfh [open $outfile w+]

# Список хостов
set hostlist {L1n L2n L3n}

foreach host $hostlist {
    set done_auth 0
    # Используем catch для отлова ошибок при подключении к серверу
    if { [catch {spawn ssh $host "./info.py | sed 's/total.*//g'"} msg] } {
        puts $outfh "SSH_FAIL: Не удалось подключиться к $host - $msg"
        continue  ; # переходим к следующему хосту
    }

    # Цикл ожидания для обработки авторизации и вывода
    while 1 {
        expect {
            -re {Enter passphrase for key '[^']+':} {
                if { $done_auth == 0 } {
                    send "passwd\r" ; # Замените "passwd" на ваш пароль
                    set done_auth 1
                }
            }
            timeout {
                puts $outfh "TIMEOUT: Не удалось подключиться к $host"
                break;
            }
            eof {
                puts $outfh $expect_out(buffer) ; # Записываем вывод
                break;
            }
        }
    }
}

close $outfh

# Форматируем вывод
exec ./format-VS-HV.sh > /root/format-allinement-output/format-allinement-output-$date.csv

Пояснения

  1. Использование catch: Это позволяет нам отследить ошибки, если команда spawn ssh не смогла подключиться к серверу. В случае ошибки мы записываем соответствующее сообщение в выходной файл.

  2. Проверка состояния соединения: Обработка различных событий, таких как timeout и eof, помогает гарантировать, что мы всегда получаем вывод или информацию об ошибке.

  3. Обработка паролей: Не забудьте заменить "passwd" на правильный пароль, если используется автоматизация ввода пароля. Убедитесь, что использование паролей сохраняет безопасность ваших данных.

  4. Форматирование даты: Дата формируется на основе текущего времени, что упрощает ведение журналов и делает ваши отчеты более организованными.

Заключение

Используя предложенные правки, ваш скрипт сможет надежно обрабатывать ошибки подключения к серверам, записывая соответствующую информацию в выходной файл. Такой подход не только улучшает читаемость кода, но и повышает его устойчивость. Если вам требуется больше деталей относительно отдельных аспектов работы скрипта, пожалуйста, дайте знать, и я с удовольствием помогу.

Оцените материал
Добавить комментарий

Капча загружается...