Настройка pipefail для одной команды конвейера

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

command1 | command2 | command3

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

set -o pipefail && command1 | command2 | command3

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

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

2
задан Alex Grin
21.01.2023 14:25 Количество просмотров материала 3537
Распечатать страницу

3 ответа

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

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

это ограничило бы эффект pipefail вариант в ячейку создать с помощью скобок (...).

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

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

если вы используете явный вызов оболочки с -c вариант вам не нужен subshell, либо с 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 - или что это на самом деле какая-то другая оболочка.

12
отвечен thkala 2023-01-22 22:13

вы можете использовать $(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 ] & & " означает, что следующая команда выполняется, только если предыдущая выполнена успешно.

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

0
отвечен Christian Glacet 2023-01-23 00:30

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

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

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

# explicitly execute with pipefail set
(set -o pipefail ; command1 | command2 | command3 )
# explicitly execute with pipefail unset
(set +o pipefail ; command1 | command2 | command3 )
0
отвечен robbat2 2023-01-23 02:47

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх