13

Мне нужно выполнить ряд командных командных оболочек из не-BASH-скрипта (а именно PHP-скрипта), например:

command1 | command2 | command3

так что, если command1 завершается с ошибкой с ненулевым кодом выхода, каждая другая команда тоже не выполняется. Пока что я придумал:

set -o pipefail && command1 | command2 | command3

Но даже при том, что это работает отлично от терминала, это производит это, если выполнено от сценария:

sh: 1: set: недопустимый параметр -o pipefail

3 ответа3

14

В командной строке Bash вы должны были бы вызвать подоболочку , чтобы избежать pipefail быть установлены впоследствии:

$ (set -o pipefail && command1 | command2 | command3)

Это ограничит влияние опции pipefail на подоболочку, создаваемую скобками (...) .

Реальный пример:

$ (set -o pipefail && false | true) && echo pipefail inactive || echo pipefail active
pipefail active

Если вы используете явный вызов оболочки с параметром -c вам не требуется подоболочка, либо с bash либо с псевдонимом sh для bash:

$ bash -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active
$ sh -c "set -o pipefail && false | true" && echo pipefail inactive || echo pipefail active
pipefail active

Так как ваш sh не принимает pipefail , я должен предположить, что это какая-то старая или модифицированная версия bash или что это вообще какая-то другая оболочка.

2

Не уверен, почему это не было упомянуто выше, но можно явно сбросить pipefail , используя set +o pipefail .

set -o pipefail
command1 | command2 | command3
set +o pipefail

Если вы выполняете фрагмент и не уверены в том, что pipefail уже установлен, вы можете использовать это с подоболочками, как предлагалось ранее:

# explicitly execute with pipefail set
(set -o pipefail ; command1 | command2 | command3 )
# explicitly execute with pipefail unset
(set +o pipefail ; command1 | command2 | command3 )
0

Вы можете использовать $(command1) в сочетании с $? :

a=$(echo "a")
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

Отпечатки "abc"

a=$(ls unexitingDir)
[ $? -eq 0 ] && b=$(echo $a"b")
[ $? -eq 0 ] && c=$(echo $b"c")
echo $c

Отпечатки "".

«[$? -eq 0] &&» означает, что следующая команда выполняется, только если предыдущая была успешной.

Это не отвечает на ваш вопрос, но это решение вашей проблемы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .