Сохранять код выхода из команды bash, несмотря на то, что вывод передается через sed

Я только что заметил, что некоторые из моих заданий CI вернулись нормально, даже если компиляция не удалась. Это было в основном потому, что команда bash, вызываемая для компиляции кода, при сбое и возвращении 1, пропускала свой вывод по конвейеру, чтобы добавить к выводу некоторые цвета и т. Д.

По сути, это сводится к следующему

      $ false; echo $? # returns 1
$ true; echo $? # returns 0
$ false | sed 's/^/OUTPUT: /' # returns 0 because sed returns 0
$ true | sed 's/^/OUTPUT: /' # returns 0 because sed returns 0

Я знаю, что на баше есть PIPESTATUS, поэтому я могу использовать ${PIPESTATUS[0]}чтобы получить код выхода команды, запущенной перед конвейером. Но как мне сделать оболочку вокруг любой команды, чтобы ее вывод передавался в sed, а затем возвращался код выхода самой команды (отбрасывая код выхода)?

Чтобы сделать его действительно универсальным, скажем, я хочу передать вывод любой команды в sed, чтобы добавить цветной префикс перед каждой строкой вывода:

      $ PREFIX="$(printf '\033[1;31m')OUTPUT: $(printf '\033[0m')"
$ ls | sed "s/^/$PREFIX/"

Как указывалось выше, из-за трубы sed, это вернет 0 независимо от того, что ls возвращается, и будет отображать содержимое каталога с каждой строкой, которой предшествует красный OUTPUT: .

Могу ли я определить функцию, псевдоним и т. Д. (Назовем это «оберткой»), чтобы я позвонил, например wrap ls *.txt таким образом, что выполняется, вывод проходит через шаблон sed, а код выхода ls *.txt сам возвращается, так что

      $ wrap ls *.txt
OUTPUT: file1.txt
OUTPUT: file2.txt
$ echo $? # displays 0 (assuming there is at least one .txt file)
$ wrap ls *.foo
ls: No such file or directory
$ echo $? # displays 1 (assuming there is NO .foo file)

1 ответ

Пытаться:

      function wrap
{
    "$@" | sed 's/^/OUTPUT: /'
    return "${PIPESTATUS[0]}"
}
Другие вопросы по тегам