Есть ли разница между '&&' и ';' символы в стандартном терминале BASH?

57

Похоже, они оба сигнализируют, что BASH начинается с другой команды, следующей за символами, но есть ли четкая разница?

Майкл Терри
источник

Ответы:

76

С этой строкой:

command1 && command2

Команда2 будет выполнена, если (и только если) Команда1 вернет нулевой статус выхода, тогда как в этой строке:

command1 ; command2

и command1, и command2 будут выполняться независимо. Точка с запятой позволяет вводить много команд в одной строке.


источник
1
Интересно! Я думал, что это может быть более удобным способом. Спасибо!
42

Вы можете попробовать разницу для себя:

  1. ls /invalid/path && echo "hello!"
    поскольку / invalid / path не существует, ls не может показать вам список каталогов. Сбой с сообщением об ошибке: «ls: / invalid / path: Нет такого файла или каталога». Вторая половина команды (эхо «Привет!») Никогда даже не выполняется , потому что первая половина не удалась.

  2. ls /invalid/path ; echo "hello!"
    Появляется то же сообщение об ошибке, что и раньше, но на этот раз выполняется вторая часть !
    ls: / invalid / path: нет такого файла или каталога
    привет!

Почему это полезно?
Предположим, вы хотите извлечь файл с именем archive.tar.gz.
Вы можете использовать команду tar zxvf archive.tar.gz && rm archive.tar.gz.
Если по какой-либо причине извлечение архива не удалось, вторая часть не выполняется! Вы можете попробовать еще раз.

Если вы используете; в той же ситуации архив удаляется, и вы не можете повторить попытку.

Кенни Рассчарт
источник
8

&&это ANDозначает, что вторая команда будет выполнена, только если первая вернула true (без ошибок).

Уорд Мюйлаерт
источник
1
&& - это «тогда» (не «и») ... см. мой ответ
Peter.O
2
@fred Я бы сказал, что это «и» с оценкой короткого замыкания - если первая часть неверна, он знает, что общий результат должен быть ложным, поэтому пропускает вторую часть. Но согласитесь, что думать об этом как о «тогда» редко имеет большое значение в этом контексте.
jg-faustus
2
@fred Хотя концептуально было бы легче понять это таким образом, я не согласен с вашим утверждением. Идея состоит в том, что при любом AND выполнении 2-й параметр становится неактуальным, если первый равен, falseи поэтому базовый код оптимизируется, чтобы отложить оценку 2-го параметра, пока он не узнает, что является первым.
Уорд Мюйлаерт
2
@fred Я не уверен, какой момент этот пример пытается сделать. &&это просто бинарный оператор, функция. Единственное «особенное» - это то, что это инфиксная запись (которая в любом случае является стандартной для большинства операторов такого типа) и отложенное выполнение второго операнда. Это отложенное выполнение действительно дает ему возможность быть использованным как нечто, что может быть концептуально рассмотрено как ifутверждение в этом контексте , но это не умаляет того факта, что его первоначально предназначенное использование находится в пределах условия фактического ifутверждения. Использование здесь действительно больше "взломать".
Уорд Мюйлаерт
3
@fred Конечно, это не троичный оператор, это просто последовательность двух операций a && b || c = (a && b) || c. Простой порядок оценки. Там действительно нет никакой тайны. Если бы вы написали их как ваши типичные функции, это было бы просто так or(and(a, b), c). Эта логика одинакова как внутри ifусловия, так и при вводе ее прямо в командную строку, поскольку &&и ||являются операторами , они принимают два операнда и возвращают другой.
Уорд Мюйлаерт
8

Обновление : я добавил как скрипт, чтобы выделить некоторые из возможных ловушек:

Поскольку никто не упомянул «||», я буду

Update2 : некоторая важная переформулировка здесь
&& подобна выражению «тогда» или «если», которое отвечает «истинно»

|| это НЕ как и «другие» из «если» даного ..
|| это как «тогда» из «если» утверждение, которое отвечает на «ложь»

Более конкретно, && проверяет $? возвращает значение предыдущего последнего выполненного оператора и передает управление оператору или вложенной оболочке сразу после && ... он передает управление только если $? правда.

|| аналогичен и часто встречается после оператора &&, но он проверяет наличие ложного возвращаемого значения ($?) из предыдущего последнего выполненного оператора ... NB! Нота Бене! Обратите внимание! .... если оператор предопределения является оператором &&, который возвращает значение false, когда вы ожидаете, что он будет истинным, то || ответит на ложь, поэтому смешивать оба на одной строке может быть рискованно

Главное, что я пытаюсь сделать, связано с ошибкой, которую я сделал. то есть:
## [[условие]] && A || B
это не ведет себя не так , как С / С ++ стиль тройным. то есть:
// (условие)? A: B
Смотрите сценарий ниже для примеров "неожиданных" результатов от "A"

Базовый тест и && и || утверждение все должно быть в одной строке ...


Запустите этот скрипт, чтобы увидеть, где что-то может пойти не так при использовании && и || Совсем недавно казнены заявление не может быть один вы ожидаете ..

[[условие]] && echo Hello || echo Goodbye .... обычно безопасен,
потому что хорошо сформированное эхо вернет true.
но как насчет доступа к файлу, который не выходит?

#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR  contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo  ======
 ((1==1)) && echo  " ((1==1)) rc=$? ..&&.. condition is true" || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && echo "  \$0  0   rc=$? ..&&.. condition is true" || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && echo  " ((1!=1)) rc=$? ..&&.. condition is true" || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && echo "  \$0  1   rc=$? ..&&.. condition is true" || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo  ======
 ((1==1)) || echo  " ((1==1)) rc=$? ..||.. condition is true" && echo  " ((1==1)) rc=$? ..&&.. condition is false"
  $0  0   || echo "  \$0  0   rc=$? ..||.. condition is true" && echo "  \$0  0   rc=$? ..&&.. condition is false"
 ((1!=1)) || echo  " ((1!=1)) rc=$? ..||.. condition is true" && echo  " ((1!=1)) rc=$? ..&&.. condition is false"
  $0  1   || echo "  \$0  1   rc=$? ..||.. condition is true" && echo "  \$0  1   rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"

exit 

Peter.O
источник
1

пытаться

false && echo "привет"

а также

ложный ; эхо "привет"

увидеть разницу

Петри Вонг
источник
0

Команда (функция, в случае скрипта) после &&выполняется в зависимости от RETVAL первой команды (функция, в случае скрипта). В случае успеха первая команда возвращает значение 0. Мы можем проверить возвращаемое значение для выполнения дальнейших команд.

theTuxRacer
источник