Негативно, якщо умова в сценарії bash


162

Я новачок у баші, і я застряг у спробі заперечити таку команду:

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
> виклик додаткової оболонки просто для виведення помилки
tijagi

Відповіді:


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
Кіра

4
Ця відповідь є непотрібним багатослівним. ifочікує твердження, яке дорівнює 0 або 1, тому ви можете використовувати саму команду та перевернути її:if ! wget ...; then ...; fi
Nils Magnus


8

Якщо ви лінуєтесь, ось короткий спосіб поводження з умовами використання ||(або) та &&(і) після операції:

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

8
У сценаріях із реального життя слід змінити команду &&після відлуння на 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.