Какова цель &&:; в скриптах bash - PullRequest
0 голосов
/ 09 мая 2018

Я столкнулся с bash-скриптом, который выполняет следующую команду в функции

set -e
rm -rf some_dir/* && :;

Какова цель && :; в этом контексте?

Edit:

Я понимаю, что это синоним к && true, но теперь я не понимаю, почему он обходит set -e

Пробуя это, я вижу, что работает следующее

#!/bin/bash -e

# false
echo false alone return 1 and fail with -e

false || true
echo "false || true return $?"

false || :;
echo "false || :; return $?"

false && true
echo "false && true return $?"

false && :;
echo "false && :; return $?"

false && :
echo "false && : return $?"

Выходы

false alone return 1 and fail with -e
false || true return 0
false || :; return 0
false && true return 1
false && :; return 1
false && : return 1

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Причину подавления эффекта set -e можно найти на странице справки:

-e      Exit immediately if a simple command (see SHELL GRAMMAR above) exits with a non-zero status.
        The shell does not exit if the command that fails is part of the  command  list  immediately
        following  a while or until keyword, part of the test in an if statement, part of a && or ||
        list, or if the command's return value is being inverted via !.  A trap on ERR, if  set,  is
        executed before the shell exits.

Для акцента: The shell does not exit if the command that fails is ... part of a && or || list

Обратите внимание, что здесь есть некоторая тонкость. Распространенной ошибкой является написание кода типа foo() { ...; rm path; #cleanup }, в котором намерение всегда должно быть успешным. Под этим я подразумеваю, что автор кода на самом деле даже не задумывался о состоянии выхода foo, но неявно ожидает, что преуспеет, и не заботится о состоянии выхода rm, забывая, что foo возвращает статус выхода rm. Код может быть переписан rm path || : для обеспечения того, чтобы foo всегда возвращался успешно, или rm path && : для возврата состояния rm, но не для выхода, если errexit включен. Честно говоря, это слишком тонко, и я считаю еще одну причину, по которой никогда не использовать set -e. Также может быть выдвинут аргумент, что вам никогда не следует полагаться на состояние выхода кода, если вы явно не exit сценарий или return из функции.

0 голосов
/ 09 мая 2018

&& легко объяснить. Со страницы bash man:

command1 && command2

команда2 выполняется, если и только если команда1 возвращает нулевое состояние выхода.

: труднее найти в документах. : является встроенным, что эквивалентно true:

:; echo $? 
0

Таким образом, в целом эта команда равна:

Рекурсивно удалите каталог, и, если rm успешен, запустите 'true'.

Это кажется ненужным, поскольку && уже «проверил», что rm возвращает true, так что это немного похоже на true && true.

Чаще всего это используется, когда вы хотите if/else, где только else что-то делает, например,

if command1; then :; else command2; fi

Хотя это полезно только в том случае, если в вашей системе нет команды true, что, возможно, будет проще для понимания последующим читателем кода. (Или вы можете использовать отрицательный тест и вообще не беспокоиться об отказе от операции).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...