Что более идиоматично в скрипте bash: `|| true` или `|| : `?

36

Я не слишком много пишу сценариев оболочки, поэтому я немного удивился, когда читал документациюgit submodule и увидел синтаксис, который они использовали в этой документации:

Ненулевой возврат команды в любом подмодуле приводит к прекращению обработки. Это можно переопределить, добавив || :в конец команды.

Я должен был посмотреть, что || :было условием для принудительного завершения команды. Каждый раз, когда мне нужно было успешно выполнить команду выхода, я использовал || true. Является ли || :считается более идиоматических?

Марк Рушаков
источник
Стоит отметить, что ||:(без пробела) также действует в bash. Он делает то же самое, что и || :или || true.
Бруно Броноски

Ответы:

38

trueне был встроен в оболочку Борна. :всегда был (это был способ ввода комментариев, прежде чем #был представлен).

Это, а также потому , что это короче типа, вероятно , главная причина , люди предпочитают :более true.

Обратите внимание на другое различие в оболочках POSIX (для bash, только в режиме POSIX): хотя trueобычная встроенная функция (даже не требуется встроенная), :это специальная встроенная функция. Это имеет несколько последствий, большинство из которых вряд ли окажут какое-либо влияние в данном конкретном случае:

  • Если :команда не выполняется, в том числе из-за сбоя перенаправления, это приводит к выходу оболочки. На практике это, вероятно, не будет иметь значения, если вы не передадите перенаправления:

    $ sh -c ': > /   ; echo HERE'
    sh: 1: cannot create /: Is a directory
    $ sh -c 'true > /; echo HERE'
    sh: 1: cannot create /: Is a directory
    HERE
  • в var=value :, varостается установленным valueпосле :возврата, не в случае true:

    $ var=1; var=2 :   ; echo "$var"
    2
    $ var=1; var=2 true; echo "$var"
    1

Также обратите внимание, что || trueработает в оболочках rcи cshсемьях, но не || :(но не отменить set -eв csh).

|| :это не то же самое, что :. Это означает или работает :иначе (то есть, если предыдущий конвейер не работает).

set -e
false

Будет ли вызвать оболочку для выхода из - за set -eи falseимеет статус выхода не равен нулю (ошибка). set -eЭффект будет отменен , если команда , которая возвращает ненулевой код выхода используется в качестве условия , как в:

if false; then ...
while false; do ...
false && : ...
false || : ...

false && :только отменяет set -e. false || :отменяет set -eи устанавливает состояние выхода, 0так что более идиоматично говорить, что мы хотим игнорировать код завершения сбоя команды. Большинство будет утверждать, что || trueэто более разборчиво (передает намерение более четко).

Стефан Шазелас
источник
5
&& :это замечательно, есть какие-нибудь документы или дальнейшее чтение по этому вопросу? Google
терпит неудачу,
5

Обычно в bash двоеточие :и trueэквивалентно.

Это || : считается более идиоматичным?

Я думаю, что это основано на контексте .

Если вы хотите return value, чтобы a или a conditionвсегда было true, вам следует использовать trueключевое слово, это сделает ваш код более четким и позволит зрителям понять, что вы хотите подчеркнуть значение true , то есть:

while true; do something

или

<commnad>
RETURN_VALUE= $? || true

И если вы хотите ничего не делать , или NOPв оболочке, вы должны использовать двоеточие:

if condition
then
    : # DO NOTHING HERE
else
    do something
fi 

или

while conditon
do
    : # DO NOTHING HERE
done
cuonglm
источник
5

Большинство из этих ответов не относятся к наиболее распространенному использованию :.

Во-первых, это обсуждение не относится к какой-либо оболочке, не являющейся производной оболочки Борна ( sh). Тем не менее, все производные оболочки Борна видят trueи :как одно и то же. Программисты раньше поощрялись к использованию, :а не trueпотому, что они :всегда были встроенными, в то время как были случаи, когда они trueне всегда были встроенными.

:имеет два использования. Это не синоним для #, но у него другая функция. При отладке вашего скрипта в a set -xстроки, где #он используется, отбрасываются анализатором и полностью игнорируются, тогда как строки с :анализируются и оцениваются. Это действительно полезно при отладке, поскольку под -xэтими строками отображаются и отображаются их значения после оценки. Это все равно что помещать printв ваш код операторы, которые отображаются только в -xрежиме. Будьте осторожны со значениями после, :поскольку они представляют собой реальный код, и побочные эффекты могут повлиять на вашу программу.

корд
источник
1
Какое второе использование?
Питер Мортенсен