Отрицание, если условие в скрипте bash


163

Я новичок в bash и застрял при попытке отменить следующую команду:

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -eq 0 ]]; then
        echo "Sorry you are Offline"
        exit 1

Это если условие возвращает истину, если я подключен к Интернету. Я хочу, чтобы это произошло наоборот, но положить что- !то не получается.


3
Где ты это положил? if ! [[ ...работает
тот другой парень

1
Вы также можете использовать его следующим образом: wget your_xxxx_params || (эхо "о, о" && выход 1)
AKS

2
> вызов subshell только для вывода ошибки
tijagi 20.10.14

Ответы:


227

Ты можешь выбрать:

if [[ $? -ne 0 ]]; then       # -ne: not equal

if ! [[ $? -eq 0 ]]; then     # -eq: equal

if [[ ! $? -eq 0 ]]; then

! инвертирует возврат следующего выражения, соответственно.


9
нужны двойные скобки? это почему?
Александр Миллс

1
@AlexanderMills: Есть несколько способов сделать это. С двойными или одинарными скобками или с testкомандой:if test $? -ne 0; then
Cyrus

4
Этот ответ не нужен многословно. ifожидает оператор, который будет либо 0, либо 1, поэтому вы можете использовать саму команду и инвертировать ее:if ! wget ...; then ...; fi
Nils Magnus

87

Лучше

if ! wget -q --spider --tries=10 --timeout=20 google.com
then
  echo 'Sorry you are Offline'
  exit 1
fi

1
Важно: оставьте пробел между !следующей и следующей командами, иначе вы будете выполнять расширение истории. unix.stackexchange.com/questions/3747/…
Роланд

2
Стивен, почему у тебя только 1 репутация?
Роланд

8

Если вам лень, вот краткий метод обработки условий с использованием ||(или) и &&(и) после операции:

wget -q --tries=10 --timeout=20 --spider http://google.com || \
{ echo "Sorry you are Offline" && exit 1; }

8
В реальных сценариях вы должны изменить команду &&после echo на a ;. Причина этого заключается в том, что если вывод перенаправляется в файл на полном диске, echoон возвращает ошибку и exitникогда не сработает. Это, вероятно, не то поведение, которое вы хотите.
Score_Under

или вы можете использовать, set -eи в случае неудачи echoвыйдет из сценария в любом случае
Якуб Боченски

4

Поскольку вы сравниваете числа, вы можете использовать арифметическое выражение , которое упрощает обработку параметров и сравнение:

wget -q --tries=10 --timeout=20 --spider http://google.com
if (( $? != 0 )); then
    echo "Sorry you are Offline"
    exit 1
fi

Обратите внимание, как вместо -ne, вы можете просто использовать !=. В арифметическом контексте нам даже не нужно прибегать $к параметрам, т. Е.

var_a=1
var_b=2
(( var_a < var_b )) && echo "a is smaller"

отлично работает Это не относится к $?специальному параметру, хотя.

Кроме того, поскольку (( ... ))ненулевые значения оцениваются как истина, т. Е. Имеет статус возврата 0 для ненулевых значений и статус возврата 1 в противном случае, мы могли бы сократить до

if (( $? )); then

но это может сбить с толку больше людей, чем стоит сэкономленное нажатие клавиш.

(( ... ))Конструкция доступна в Bash, но не требует спецификации POSIX оболочки (упоминается в качестве возможного расширения, хотя).

Все это , как говорится, это лучше избегать $?вообще , на мой взгляд, как и в ответ Коула и ответ Стивена .



@ DavidC.Rankin О, я этого не нашел! Так что это упоминается как расширение, но не обязательно. Я исправлю
Бенджамин В.

1
Да, тот всегда меня тоже заводил. Это, конечно, облегчает жизнь в раковине, хотя:)
Дэвид С. Ранкин

4

Вы можете использовать неравное сравнение -neвместо -eq:

wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -ne 0 ]]; then
    echo "Sorry you are Offline"
    exit 1
fi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.