Оператор "і" для оператора "якщо" в Bash


168

Я намагаюся створити простий сценарій Bash, щоб перевірити, чи веб-сайт не працює, і чомусь оператор "і" не працює:

#!/usr/bin/env bash

WEBSITE=domain.com
SUBJECT="$WEBSITE DOWN!"
EMAILID="an@email.com"
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" ]]

Чи можете ви порадити, коли використовувати:

  • одинарні та подвійні квадратні дужки
  • дужки

?


3
Не могли б ви бути більш точними щодо того, що "не працює"? У вас є певне повідомлення про помилку, чи це просто не забезпечує очікуваного результату?
Жульєн Вівенот

Я насправді отримував "очікується, що оператор очікується", тому, схоже, цитування допомагає
HTF

-aмає подвійність. Якщо використовується з testкомандою стилю оболонки Bourne [, він також означає and. Якщо він використовується як умовний вираз, він тестує, чи існує файл. Так, це заплутано, найкраще уникати.
cdarke

Перевірте це: theunixshell.blogspot.com/2013/05/…
Vijay

Відповіді:


254

Те, що ви маєте, має працювати, якщо тільки ${STATUS}воно не порожнє. Напевно, було б краще зробити:

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

або

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

Важко сказати, оскільки ви нам не показали, що саме відбувається з вашим сценарієм.

Особиста думка: ніколи не використовуйте [[. Він пригнічує важливі повідомлення про помилки і не переноситься на різні оболонки.


2
Якщо STATUSпорожній, код з @HTF не вдалося б увімкнути -ne: unary operator expected. У вашому випадку воно не вдасться integer expression expected, чи не так?
Жульєн Вівенот

1
Я розумію, що. Але ви виділите проблему, яка $STATUSможе бути порожньою, і пропонуєте рішення (цитуючи це). Ваше рішення все ще не вдається з порожнім STATUS, це все, що я мав на увазі.
Жульєн Вівенот

1
@jvivenot У вас є бал. (Моя відповідь на ваш коментар була зроблена ще до того, як ви відредагували ваш коментар, коли ваш коментар просто прочитав "код ... не вдалося б". Просте рішення - використовувати ${STATUS:-0". Відредагувати.
William Pursell

На жаль, ваше редагування все ще не працює. Наприклад: STATUS=; [ $STATUS -ne 13 ] 2>/dev/null && echo fooне виводить foo, хоч і повинен (порожній відрізняється від 13). Те, що ви спочатку запропонували, ${STATUS:-0}виглядає набагато краще.
Жульєн Вівенот

@jvivenot Використання ${STATUS:-0}не вдасться STATUS=foo, але ! [ "$STATUS" -eq 200 ] 2> /dev/null && echo fooпрацює. ІМО, все ж краще уникати -eqта використовувати !=.
Вільям Перселл

28

Спробуйте це:

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

працював на мене. Я думаю, що може бути декілька способів, але я поки що задоволений цим.
Кушаль Ашок

27

Спробуйте це:

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

або

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

плюс за найясніший приклад
Pawel Cioch

12

Цитата:

Оператор "-a" також не працює:

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

Для більш детального пояснення: [і ]це не зарезервовані слова Баша. ifКлючовим слово вводить умовне бути оцінені роботами (умовний вірно , якщо повертається значення РОБОЧОГО МІСЦЯ є 0або хибним в іншому випадку).

Для тривіальних тестів є 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, але в цьому випадку воно розбирається лише як звичайний аргумент команди, тому що воно не знаходиться в передній частині команди.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.