Здесь я пытаюсь написать сценарий оболочки, который продолжает тестировать мой сервер и отправлять мне электронные письма, когда он отключается.
Проблема в том, что когда я выхожу из ssh-соединения, несмотря на то, что он запускается с ним &
в конце команды, например ./stest01.sh &
, он автоматически попадает в else и продолжает непрерывно отправлять мне письма, пока я снова не захожу и не уничтожаю его.
#!/bin/bash
while true; do
date > sdown.txt ;
cp /dev/null pingop.txt ;
ping -i 1 -c 1 -W 1 myserver.net > pingop.txt &
sleep 1 ;
if
grep "64 bytes" pingop.txt ;
then
:
else
mutt -s "Server Down!" myemail@address.com < sdown.txt ;
sleep 10 ;
fi
done
linux
shell-script
grep
ping
Vasconcelos1914
источник
источник
:
? Было бы разумно, если бы это была точка с запятой;
...:
ничего не делает. Это то, для чего он предназначен. Здесь, вместо того, чтобы перевернуть тест, они используют его, чтобы сделать no-op раньшеelse
.Ответы:
Когда GNU
grep
пытается записать свой результат, он потерпит неудачу с ненулевым состоянием выхода, потому что ему некуда записать вывод, потому что соединение SSH разорвано.Это означает, что
if
утверждение всегда принимаетelse
ветвь.Чтобы проиллюстрировать это (это не совсем то, что происходит в вашем случае, но оно показывает, что происходит, если GNU
grep
не может записать свой вывод):Здесь мы
grep
для строки, котораяecho
производит, но мы закрываем оба выходных потока дляgrep
того, чтобы он не мог нигде записать. Как видите, состояние выхода GNUgrep
- 2, а не 0.Это относится к GNU
grep
,grep
в системах BSD не будет вести себя так же:Чтобы исправить это, убедитесь, что скрипт не генерирует вывод. Вы можете сделать это с
exec >/dev/null 2>&1
. Кроме того, мы должны использоватьgrep
его с-q
опцией, так как мы вообще не заинтересованы в том, чтобы увидеть вывод из него (это, как правило, также ускорит процесс, такgrep
как не нужно анализировать весь файл, но в этом случае это очень мало разница в скорости так как файл очень маленький).Короче говоря:
Вы также можете
ping
напрямую использовать тест , устраняя необходимость в одном из промежуточных файлов (а также избавляясь от другого промежуточного файла, который действительно содержит только метку даты):В обоих вариантах сценария, приведенного выше, я выбираю выход из цикла при невозможности связаться с хостом, просто чтобы минимизировать количество отправляемых писем. Вместо этого вы можете заменить на
break
egsleep 10m
или что-то, если вы ожидаете, что сервер в итоге снова заработает.Я также немного подправил параметры, используемые с, так
ping
как-i 1
не имеет особого смысла-c 1
.Короче (если вы не хотите, чтобы он продолжал отправлять электронные письма, когда хост недоступен):
Поскольку задание cron выполняется каждую минуту (будет продолжаться отправка писем каждую минуту, если сервер продолжает не работать):
источник
>&-
закроет fd (как в случае, дескриптор файла 1 закрыт), в то время как закрытие соединения SSH будет иметь другой эффект (дескриптор файла будет все еще рядом, но не связан ни с чем на другой стороне.) Я думаю, что точка все еще стоит, что означает, что GNU grep завершает работу с ненулевым значением, если он пытается записать вывод, и это не удается. Да, лучшее решение - это просто проверить состояние выхода ping напрямую.exec </dev/null >/dev/null 2>&1
в начале. Таким образом, если, например,ping
решит написать что-то в stderr, это не вызовет проблем./dev/null
отсюда, но я разобрался с выводом. Спасибо за предложение.