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

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

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 вручную
  • Ошибка анализа zsh после псевдонима do = ...
  • Как выполнить несколько команд вместе в фоновом режиме?
  • Сильная команда таймаута в zsh
  • Zsh запрашивает полную ширину с пользовательским вводом в следующей строке
  • Есть ли LC_COLLATE, который сортирует точку перед тире?
  • Изменение шаблонов гвоздики zsh для использования с cp
  • Расширение с числами в человекообразном формате
  • Поиск в обратном и прямом направлениях осуществляется с помощью vi-режима в zsh
  • Как увеличить историю в oh-my-zsh?
  • Команда Wrap в подсказке
  • Interesting Posts

    Установка пакета FreeBSD в автономном режиме

    Асинхронный RPROMPT?

    Найдите файл и создайте символическую ссылку для родителя с помощью find и -exec

    Почему PGID моего дочернего процесса обрабатывает не PID родителя?

    Загрузка X ресурсов из .Xresources и .Xdefaults для Emacs

    Как запустить keychain из gdm?

    Внешние команды в AWK

    Запустить debian графический установщик изнутри debian?

    Как я могу выполнить команду `history` и не иметь номеров строк, чтобы я мог копировать несколько строк?

    Может ли кто-нибудь уточнить для меня о глобальной переменной в этом сценарии оболочки?

    Два сетевых интерфейса (eth0 и eth1) одной и той же машины Linux не могут пинговать друг друга

    Как найти md5sum файлов на удаленных машинах, выполнив ssh?

    Откройте новый bash с полномочиями sudo без повторного ввода пароля

    Как узнать, что такое мой отпечаток пальца ssh-ключа?

    Любые встроенные методы Linux для устройств типа AXI-burst?

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