Как фиксировать статус выхода команды без конечного результата в конвейере?

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

command_1 ... | command_2 ... | command_3 ... | ... | command_n 

… Я хотел бы знать, как захватить статус выхода command_1 , или command_2 , или command_3 , и т. Д. ( command_3 , захват статуса command_n является тривиальным).

Кроме того, в случае, если это имеет значение, этот конвейер встречается внутри функции оболочки zsh.


Я попытался захватить статус выхода command_1 с чем-то вроде

 function_with_pipeline () { local command_1_status=-999999 # sentinel value { command_1 ...; command_1_status=$? } | command_2 ... | ... | command_n ... } 

… но после запуска конвейера значение переменной command_1_status прежнему было дозорным значением.


FWIW, вот рабочий пример, где в конвейере есть только две команды:

 foo ... | grep ... 

foo – функция, определенная для этого примера, например:

 foo () { (( $1 & 1 )) && echo "a non-neglible message" (( $1 & 2 )) && echo "a negligible message" (( $1 & 4 )) && echo "error message" >&2 return $(( ( $1 & 4 ) >> 2 )) } 

Цель состоит в том, чтобы зафиксировать статус выхода вызова для foo в конвейере.

Функция function_with_pipeline реализует (в конечном счете, неэффективную) стратегию, описанную выше, для этого:

 function_with_pipeline () { local foo_status=-999999 # sentinel value { foo $1; foo_status=$? } | grep -v "a negligible message" printf '%d\ndesired: %d; actual: %d\n\n' $1 $(( ( $1 & 4 ) >> 2 )) $foo_status } 

Цикл ниже выполняет function_with_pipeline function_with_pipeline. Результат показывает, что значение локальной переменной foo_status ничем не отличается от того, как она была запущена.

 for i in $(seq 0 7) do function_with_pipeline $i done # 0 # desired: 0; actual: -999999 # # a non-neglible message # 1 # desired: 0; actual: -999999 # # 2 # desired: 0; actual: -999999 # # a non-neglible message # 3 # desired: 0; actual: -999999 # # error message # 4 # desired: 1; actual: -999999 # # error message # a non-neglible message # 5 # desired: 1; actual: -999999 # # error message # 6 # desired: 1; actual: -999999 # # error message # a non-neglible message # 7 # desired: 1; actual: -999999 # 

Я получаю те же результаты, если я опускаю local декларацию в определении foo_status .

2 Solutions collect form web for “Как фиксировать статус выхода команды без конечного результата в конвейере?”

Для zsh существует специальный массив pipestatus , поэтому попробуйте

 command_1 ... | command_2 ... | command_3 

а также

 echo $pipestatus[1] $pipestatus[2] $pipestatus[3] 

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


Для справки, это PIPESTATUS (с заглавными буквами) в bash .

mispipe работает в любой оболочке. Синтаксис (по сравнению с регулярным каналом) работает следующим образом:

 mispipe true false ; echo $? # returns exit code of 1st command `true` true | false ; echo $? # returns exit code of 2nd command `false` 

Вывод:

 0 1 

Что делать, если есть более двух программ:

 # this still returns exit code of 1st command `true` mispipe true 'false | false | false' ; echo $? 

Вывод:

 0 

Несмотря на отсутствие видимого | , он по-прежнему ведет себя как труба:

 yes | mispipe head 'wc -c' 

Вывод:

  20 
  • Как добавить статус батареи в zsh в крайнем правом положении?
  • Как я могу передать только stderr в zsh?
  • zsh: установить TERM = screen-256color в tmux, но xterm-256color без tmux
  • Файлы без расширения .sh, не считающиеся для автозаполнения в zsh
  • Завершения работы перестали работать после обновления zsh
  • Пополнение Git для псевдонимов доступно только после запуска `git reflog`
  • Список завершения автозапуска Zsh в файл или меньше
  • ls -l - групповые каталоги - сначала (действуют также на символические ссылки)
  • Список всех согласованных файлов, начиная с индекса
  • Вывод цитат для scp
  • предотвращение очистки экрана при выходе из сеанса ssh
  • Interesting Posts

    Правильное литье типов в сценарии оболочки для использования с циклом while и модулем

    Установка: какой раздел подкачки использовать для установки ArchLinux на мой ноутбук Ubuntu 16.04 (без USB)?

    Как отобразить всю строку текста?

    Использовать для цикла в find exec

    Как смонтировать файловые системы с размерами блоков> 4 КБ?

    Имя процесса после убийства

    Как правильно настроить «Creative Sound Core 3D» на Debian Jessie?

    Для сообщений электронной почты, где указано поле без двоеточия From?

    Как удалить приветственное сообщение «У вас есть почта»

    Как получить время безотказной работы в разных ОС?

    Каким уведомлением отправляется Firefox при завершении загрузки?

    как использовать rsync (используя ssh без пароля), с sudo только на локальной стороне?

    SSH-туннелирование с несколькими динамическими портами

    Как подключить USB-накопитель в правиле udev?

    системный таймер каждые 2 часа через 30 минут после часа?

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