Чи є різниця між "&&" та ";" символів у стандартному терміналі BASH?


56

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

Відповіді:


75

За допомогою цього рядка:

command1 && command2

command2 буде виконуватися, якщо (і тільки якщо) command1 повертає статус виходу нульовий, тоді як у цьому рядку:

command1 ; command2

і команда1, і команда2 будуть виконуватися незалежно. Точка з комою дозволяє вводити багато команд в одному рядку.


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

42

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

  1. ls /invalid/path && echo "hello!"
    оскільки / invalid / path не існує, я не можу показати вам список каталогів. Він не вдасться при повідомленні про помилку: "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і тому базовий код оптимізується для відстрочення оцінки другого параметра, поки він не дізнається, що таке перший.
Ward Muylaert

2
@fred Я не впевнений, що саме цей приклад намагається зробити. &&це лише бінарний оператор, функція. Єдине "особливе" те, що це позначення інфіксації (що так чи інакше є стандартним для більшості операторів такого типу) та затримка виконання другого операнда. Це відкладене виконання дійсно дає можливість використовувати його як те, що в цьому контексті можна концептуально розглядати як ifвислів , але це не віднімає від того, що його спочатку призначене використання знаходиться в умові фактичного твердження. Використання тут справді більше "хак". if
Ward Muylaert

3
@fred Звичайно, це не потрійний оператор, це просто послідовність двох операцій a && b || c = (a && b) || c. Простий порядок оцінювання. Там справді немає таємниці. Якби ви писали їх як свої типові функції, це було б просто так or(and(a, b), c). Ця логіка та сама в межах ifумовно, а також при введенні його прямо в командному рядку , так як &&і ||є оператори , вони приймають два операнда і вони повертають інший.
Ward Muylaert

8

Оновлення : я додав як сценарій, щоб виділити деякі можливі пастки:

Тому що ніхто більше не згадав "||", я буду

Update2 : деяке важливе переформулювання тут
&& - це як твердження "тоді" "if", яке відповідає "true"

|| це НЕ подобається «ще» з «якщо» Постулати ..
|| - це як твердження "тоді" "if", яке відповідає "false"

Більш детально && тестує $? повертає значення попереднього останнього виконаного оператора і передає керування оператору або підкожці відразу після && ... воно передає контроль лише якщо $? правда.

|| подібний, і його часто можна побачити після заяви &&, але він перевіряє хибне повернене значення ($?) з попереднього останнього виконаного оператора ... Примітка! , Нота Бене! Зауважте, що .... .... якщо попередній вислів - це && твердження, яке повертається помилковим, коли ви очікуєте, що це правда, тоді || відповість на помилкове, тому змішування обох на одній лінії може бути ризикованим

Головне, що я намагаюся зробити, - це стосовно допущеної помилки. тобто:
## [[умова]] && A || B
це НЕ поводиться не так , як C / ++ стиль троичного C. тобто:
// (умова)? A: B
Дивіться сценарій нижче для прикладів "несподіваних" результатів від "A"

Основний тест та && та || всі заяви повинні бути в одному рядку ...


Запустіть цей скрипт, щоб побачити, де все може піти не так під час використання && та ||
Очікуване за останнім часом може бути не таким, яке ви очікуєте ..

[[умова]] && відлуння Привіт || echo Goodbye .... зазвичай безпечний,
тому що добре сформоване відлуння повернеться справжнім.
а як щодо доступу до файлу, який не виходить?

#!/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 


1

спробуйте

хибне && відлуння "привіт"

і

помилковий ; відлуння "привіт"

побачити різницю


0

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

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