Похоже, что они оба сигнализируют, что BASH начинается с другой команды, следующей за символами, но есть ли четкая разница?
&&
равно AND
, что означает, что вторая команда будет выполнена, только если первая вернула значение true (без ошибок).
Вы можете сами попробовать разницу:
ls /invalid/path && echo "hello!"
, поскольку / invalid / path не существует, ls не может показать вам каталог листинга. Сбой с сообщением об ошибке: «ls: / invalid / path: нет такого файла или каталога».
вторая половина команды (echo "hello!") даже не выполняется , потому что первая половина не выполнена.
ls /invalid/path ; echo "hello!"
Появляется то же сообщение об ошибке, что и раньше, но на этот раз исполняется вторая часть !
путь: нет такого файла или каталога
привет!
Почему это полезно?
Предположим, вы хотите извлечь файл с именем archive.tar.gz
Вы можете использовать команду tar zxvf archive.tar.gz && rm archive.tar.gz
.
Если по какой-либо причине извлечение архива не удалось, вторая часть не выполняется! Вы можете попробовать еще раз.
Если вы используете; в той же ситуации архив удаляется, и вы не можете повторить попытку.
С этой строкой:
command1 && command2
команда2 будет выполнена, если (и только если) команда1 вернет нулевой статус выхода, тогда как в этой строке:
command1 ; command2
и команда1, и команда2 будет выполняться независимо. Точка с запятой позволяет вводить много команд в одной строке.
попробуйте
false && echo "hello"
и
false ; echo "hello"
увидеть разницу
Команда (функция, в случае сценария) после &&
выполняется в зависимости от RETVAL первой команды (функции, в случае сценария). В случае успеха первая команда возвращает значение 0. Мы можем проверить возвращаемое значение для выполнения дальнейших команд.
Обновление: я добавил как сценарий к highight некоторые возможные прерывания:
Поскольку никто еще не упомянул "||", я буду
Update2: некоторое важное перефразирование здесь
&& похож "затем", "если" оператор, который отвечает на "истинный"
|| "еще" не похож "если" statment..
|| похож "затем", "если" оператор, который отвечает на "ложь"
Более конкретно && тестирует $? возвращаемое значение предыдущего последний раз выполнило оператор и передает управление к оператору или подоболочке сразу после &&... это только передает управление если $? верно.
|| подобно, и часто замечается после && оператора, но он тестирует на ложное возвращаемое значение ($?) от предыдущего последний раз выполняемый оператор... NB!, Нотабене! Обратите внимание!...., если predecing оператор является && оператором, который возвращает false, когда Вы будете ожидать, что он, чтобы быть верным, затем || ответит на ложь, так смешивание обоих на той же строке может быть опасным
Основное мнение, которое я пытаюсь высказать, относительно ошибки, которую я сделал. т.е.:
## [[условие]] && || B
не не ведет себя как троичный стиль C/C++. т.е.:
//(условие)? A: B
См. сценарий ниже для примеров "неожиданных" результатов "A"
Базовый тест и && и || оператор должны все быть на той же строке...
Запустите этот скрипт для наблюдения, где вещи могут пойти не так, как надо при использовании && и ||
Последний раз выполняемый оператор не может быть тем, который Вы ожидаете..
[[условие]] && эхо Привет || эхо До свидания.... обычно безопасно,
becaue хорошо сформированное эхо возвратит 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