bash: как распространять ошибки в замещении процесса?

Я хочу, чтобы мои сценарии оболочки терпели неудачу, когда команда, выполненная с ними, терпит неудачу.

Обычно я делаю это с помощью:

set -e set -o pipefail 

(обычно я добавляю set -u также)

Дело в том, что ни одно из вышеперечисленных работ не связано с замещением процесса. Этот код печатает «ok» и выходит с кодом возврата = 0, в то время как я хотел бы, чтобы он завершился неудачей:

 #!/bin/bash -e set -o pipefail cat <(false) <(echo ok) 

Есть ли что-то эквивалентное «pipefail», но для замещения процесса? Любой другой способ передать команде вывод команд, поскольку они были файлами, но поднимать ошибку всякий раз, когда какая-либо из этих программ выходит из строя?

Решение бедного человека обнаружило бы, если эти команды пишут stderr (но некоторые команды пишут stderr в успешных сценариях).

Еще одно решение, совместимое с posix, будет использовать именованные каналы, но мне нужно, чтобы эти команды-that-use-process-substitution как oneliners, созданные на лету от скомпилированного кода, и создание именованных каналов усложняли бы вещи (дополнительные команды, ошибка захвата для удаление их и т. д.)

  • Запуск удаленной команды с ssh с получением «bash: / dev / fd / 63: Нет такого файла или каталога»
  • Как читать из stdin при замене процесса?
  • Как запустить chrome из командной строки с помощью замены процесса?
  • Изменить местоположение замещения процесса zsh '= ()'
  • Использование подстановки процесса для обмана программ, ожидающих файлы, с конкретными расширениями в качестве аргумента?
  • Почему замена процесса <() не работает с ssh -F
  • Дэш-эквивалент саморасправки выхода скрипта
  • Как открыть файл с заменой процесса из php?
  • 2 Solutions collect form web for “bash: как распространять ошибки в замещении процесса?”

    Вы могли бы обойти эту проблему только с этим, например:

     cat <(false || kill $$) <(echo ok) other_command 

    Подселлем скрипта является SIGTERM d перед выполнением второй команды ( other_command ). Команда echo ok выполняется «иногда»: проблема в том, что подстановки процесса асинхронны. Нет никакой гарантии, что команда kill $$ выполняется до или после команды echo ok . Речь идет о планировании операционных систем.

    Рассмотрим сценарий bash следующим образом:

     #!/bin/bash set -e set -o pipefail cat <(echo pre) <(false || kill $$) <(echo post) echo "you will never see this" 

    Результатом этого скрипта может быть:

     $ ./script Terminated $ echo $? 143 # it's 128 + 15 (signal number of SIGTERM) 

    Или:

     $ ./script Terminated $ pre post $ echo $? 143 

    Вы можете попробовать его, и после нескольких попыток вы увидите два разных порядка на выходе. В первом сценарий был прерван до того, как две другие команды echo могли записать в дескриптор файла. Во втором случае команда false или kill была запланирована после команд echo .

    А точнее: signal() системного вызова signal() утилит-убийцы, который посылает сигнал SIGTERM в процесс оболочки, был запланирован (или был доставлен) позже или ранее, чем системные вызовы echo write() .

    Но, однако, сценарий останавливается, а код выхода не равен 0. Поэтому он должен решить вашу проблему.

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

    Рекомендации:

    Для записи, и даже если ответы и комментарии были хорошими и полезными, я закончил реализацию чего-то немного другого (у меня были некоторые ограничения на получение сигналов в родительском процессе, о которых я не упоминал в вопросе)

    В принципе, я закончил делать что-то вроде этого:

     command <(subcomand 2>error_file && rm error_file) <(....) ... 

    Затем я проверяю файл ошибки. Если он существует, я знаю, какая подкоманда потерпела неудачу (и может быть полезно содержимое файла error_file). Более подробный и хакерский, который я изначально хотел, но менее громоздкий, чем создание именованных каналов в одном слоте bash.

    Linux и Unix - лучшая ОС в мире.