Проверка успешности команды в операторе bash `if [ .. ]`
Я пытаюсь автоматизировать резервное копирование наших приложений. Частью процесса является проверка статуса выхода egrep
в if
заявление:
if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
[ egrep -i -q "error|warning|fatal|missing|critical" "$File" ]
then
echo "testing"
fi
Я ожидал, что это выведет testing
потому что файл существует и egrep
возвращает успех, но вместо этого я получаю ошибку:
-bash: [: too many arguments
Я пробовал со всеми видами синтаксиса - дополнительные скобки, кавычки и т. Д., Но ошибка все еще сохраняется.
Пожалуйста, помогите мне понять, где я иду не так.
2 ответа
Вы делаете общую ошибку, полагая, что [
является частью if
синтаксис оператора Это не; синтаксис if
это просто
if command; then
... things which should happen if command's result code was 0
else
... things which should happen otherwise
fi
Один из общих command
мы используем [
который является псевдонимом для команды test
, Это простая команда для сравнения строк, чисел и файлов. Он принимает довольно узкую комбинацию аргументов и имеет тенденцию генерировать вводящие в заблуждение и вводящие в заблуждение сообщения об ошибках, если вы не передадите ему ожидаемые аргументы. (Или, скорее, сообщения об ошибках адекватны и полезны, как только вы к этому привыкнете, но их легко понять, если вы не используете их.)
Здесь вы хотите проверить результат команды egrep
:
if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
egrep -i -q "error|warning|fatal|missing|critical" "$File"
then
echo "testing"
fi
В общем случае command
может быть конвейером или списком команд; затем код выхода из последней команды - это статус, который if
рассмотрим, аналогично тому, как последняя команда в сценарии определяет состояние выхода из сценария.
Эти составные команды могут быть сколь угодно сложными, как
if read thing
case $thing in
'' | 'quit') false;;
*) true;;
esac
then ...
но на практике вы редко видите более одной команды в if
заявление (хотя это не неслыханно; ваше сложное заявление с ||
хороший пример!)
Исторические причины test
в качестве общей кухонной раковины вещей авторы не хотели делать часть синтаксиса if
является одним из менее привлекательных конструкций оригинальной оболочки Bourne. Баш и zsh
предложить альтернативы, которые являются менее громоздкими (например, [[
двойные скобки в bash) и конечно же POSIX test
гораздо более вспыльчивый, чем оригинальное творение Bell Labs.
Это работает: поместите ваш egrep в "$()", удалите -q и сравните строку:
if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
[ "$(egrep -i 'error|warning|fatal|missing|critical' $File)" != "" ];
then
echo "testing";
fi