Объединение канала с состоянием выхода в скрипте bash.
У меня есть команда bash shell-script, которая запускает date, если make завершается успешно (завершается с нулевым статусом выхода) и наоборот:
make && date
но теперь я хочу обработать его вывод, например
make | sed s/a/A/
Если я сделаю
make | sed s/a/A/ && date
дата запускается, даже если make потерпел неудачу
Если я вместо этого
make && date | sed s/a/A/
sed обрабатывает вывод даты вместо make.
Знаете ли вы о каком-либо решении? Спасибо!
PS я пробовал это:
(make | sed s/a/A/) && date
дата по- прежнему работает, когда make не удается.
(make && (date > /dev/null)) | sed s/a/A/
дата не запускается, когда make успешен.
3 ответа
Если у вас есть оболочка с подстановкой процесса (bash делает, posix shell нет), чем
make > >(sed s/a/A/) && date
должен делать свое дело, за исключением bash, он не ждет sed (кажется, zsh делает, но я только попробовал, но не проверил doc), поэтому выходные данные date могут быть получены до последней строки вывода sed. В простой оболочке posix вы можете использовать немного более сложную конструкцию
((make && date >&3) | sed s/a/A/) 3>&1
Дата может снова запуститься до того, как sed обработает все, поэтому ее вывод может снова прийти до последней строки вывода sed.
Если вы хотите, чтобы дата запускалась только после того, как sed обработал все, ваш единственный шанс - сохранить где-нибудь статус make. Что-то вроде:
(make && touch make-succeeded) | sed s/a/A/
rm make-succeeded 2>/dev/null && date
злоупотребляя тем фактом, что если файл не существует, rm (без -f) выйдет с ненулевым статусом и отключит сообщение об ошибке с перенаправлением. Однако, как уже упоминал Фредрик, в bash действительно есть место, где он сохраняет статус выхода, поэтому в bash вы можете:
make | sed s/a/A/
[ 0 -eq $PIPESTATUS[0] ] && date
Включи pipefail
в make
подоболочка.
(set -o pipefail; make 2>/dev/null | sed s/a/A/) && date
В основном, как это;
my_make () {
local rc
make >tmp
rc=$?
sed s/a/A/ tmp
rm tmp
return $rc
}
Временный файл, очевидно, должен обрабатываться надлежащим образом; это пустяки, чтобы сосредоточиться на проблеме под рукой. Возможно, вы могли бы вообще избежать временного файла, если вы умны с файловыми дескрипторами, но сейчас пятница, и мне нужно больше кофе.