Мне нужно выполнить ряд командных командных оболочек из не-BASH-скрипта (а именно PHP-скрипта), например:
command1 | command2 | command3
так что, если происходит command1
сбой с ненулевым кодом выхода, каждая другая команда тоже не выполняется. Пока что я придумал:
set -o pipefail && command1 | command2 | command3
Но даже при том, что это работает отлично от терминала, это производит это, если выполнено от сценария:
sh: 1: set: недопустимый параметр -o pipefail
linux
command-line
shell
pipe
Десмонд Хьюм
источник
источник
/bin/sh
не нравитсяset -o pipefail
. Это на самом делеbash
замаскированный, или это другая оболочка? Когдаbash
запускается как/bin/sh
, он принимаетset -o pipefail
?/bin/sh set -o pipefail
он говорит/bin/sh: 0: Can't open set
(то же самое сsudo
). Надеюсь, я проверил это правильно. Система Ubuntu 12./bin/sh -c "set -o pipefail"
; как бы то ни было, оболочка пыталась выполнить скрипт в текущем каталогеset
и не нашла его./bin/sh -c "set -o pipefail"
не работает, ноbash -c "set -o pipefail"
работает./bin/sh
который не распознаетset -o pipefail
. Следовательно, вам нужно убедиться, что скрипт запускается/bin/bash
вместо/bin/sh
. Или, если вы уверены, смелый - и, вероятно, безрассудный - смените/bin/sh
его на ссылку или копию/bin/bash
вместо того, с какой оболочкой он связан или является копией. Если вы уверены, что/bin/sh
это такbash
, то вы используете поведение, котороеbash
не раскрывается при запуске как/bin/sh
; использоватьbash
какbash
.Ответы:
Из командной строки Bash вам нужно будет вызывать подоболочку, чтобы избежать
pipefail
ее последующей настройки:Это ограничит влияние
pipefail
опции на подоболочку, создаваемую скобками(...)
.Настоящий пример:
Если вы используете явный вызов оболочки с
-c
опцией, вам не нужна подоболочка, сbash
или сsh
псевдонимомbash
:Поскольку ваша опция
sh
не принимает этуpipefail
опцию, я должен был бы предположить, что она является какой-то более старой или модифицированной версиейbash
- или что это фактически какая-то другая оболочка.источник
$
в первой части часть команды это просто командная строка? Пробовал в обе стороны, на самом деле не сработало.bash -c
Способ всегда работает, не слишком элегантный Тхо ..Не уверен, почему это не было упомянуто выше, но это можно явно сбросить
pipefail
, используяset +o pipefail
.Если вы выполняете фрагмент и не знаете о
pipefail
уже установленном, вы можете использовать это с подоболочками, как предлагалось ранее:источник
Вы можете использовать $ (command1) в сочетании с $? :
Отпечатки "abc"
Отпечатки "".
«[$? -eq 0] &&» означает, что следующая команда выполняется, только если предыдущая была успешной.
Это не отвечает на ваш вопрос, но это решение вашей проблемы.
источник
command1 && command2 && command3