Bash - оператор "и" для оператора "if"

Я пытаюсь создать простой bash script, чтобы проверить, не упал ли сайт и почему-то оператор "и" не работает:

#!/usr/bin/env bash

WEBSITE=domain.com
SUBJECT="$WEBSITE DOWN!"
EMAILID="[email protected]"
STATUS=$(curl -sI $WEBSITE | awk '/HTTP\/1.1/ { print $2 }')
STRING=$(curl -s $WEBSITE | grep -o "string_to_search")
VALUE="string_to_search"

if [ $STATUS -ne 200 ] && [[ "$STRING" != "$VALUE" ]]; then
        echo "Website: $WEBSITE is down, status code: '$STATUS' - $(date)" | mail -s "$SUBJECT" $EMAILID
fi

Оператор "-a" также не работает:

if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]

Не могли бы вы также посоветовать, когда использовать:

  • одиночные и двойные квадратные скобки
  • скобка

Ответ 1

То, что у вас есть, должно работать, если ${STATUS} не пусто. Вероятно, было бы лучше сделать:

if ! [ "${STATUS}" -eq 200 ] 2> /dev/null && [ "${STRING}" != "${VALUE}" ]; then

или же

if [ "${STATUS}" != 200 ] && [ "${STRING}" != "${VALUE}" ]; then

Трудно сказать, так как вы не показали нам точно, что не так с вашим сценарием.

Личное мнение: никогда не используйте [[. Он не переносим на разные оболочки.

Ответ 2

Попробуйте следующее:

if [ $STATUS -ne 200 -a "$STRING" != "$VALUE" ]; then

Ответ 3

Цитата:

Оператор "-a" также не работает:

если [$ STATUS -ne 200] -a [[ "$ STRING"!= "$ VALUE" ]]

Для более подробного объяснения: [ и ] не являются зарезервированными словами bash. Ключевое слово if вводит условие, которое должно быть оценено заданием (условное значение true, если возвращаемое значение задания равно 0 или false в противном случае).

Для тривиальных тестов существует программа test (man test).

Поскольку некоторые строки поиска, такие как if test -f filename; then foo bar; fi и т.д., раздражают, в большинстве систем вы найдете программу под названием [, которая на самом деле является только символической ссылкой на программу test. Когда test вызывается как [, вы должны добавить ] в качестве последнего позиционного аргумента.

Итак, if test -f filename в основном совпадает (с точки зрения процессов, порожденных) как if [ -f filename ]. В обоих случаях программа test будет запущена, и оба процесса должны вести себя одинаково.

Здесь ваша ошибка: if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]] будет анализировать на if + некоторое задание, а работа - все, кроме самого if. Задание - это простая команда (bash говорить за что-то, что приводит к одному процессу), что означает, что первое слово ([) - это команда, а остальные - его позиционные аргументы. Остальные аргументы остаются после первого ].

Также нет, [[ действительно является ключевым словом bash, но в этом случае он анализируется только как нормальный командный аргумент, потому что он не находится в начале команды.

Ответ 4

Попробуй это:

if [ ${STATUS} -ne 100 -a "${STRING}" = "${VALUE}" ]

или же

if [ ${STATUS} -ne 100 ] && [ "${STRING}" = "${VALUE}" ]