Получить код выхода из подоболочки через каналы - PullRequest
13 голосов
/ 14 февраля 2012

Как я могу получить код выхода wget из процесса subshell?

Итак, основная проблема в том, что $? равен 0. Где можно найти $?=8?

$> OUT=$( wget -q "http://budueba.com/net" | tee -a "file.txt" ); echo "$?"
0

На самом деле работает без tee.

$> OUT=$( wget -q "http://budueba.com/net" ); echo "$?"
8

Но массив ${PIPESTATUS} (я не уверен, что он связан с этим случаем) также не содержит этого значения.

$> OUT=$( wget -q "http://budueba.com/net" | tee -a "file.txt" ); echo "${PIPESTATUS[1]}"    

$> OUT=$( wget -q "http://budueba.com/net" | tee -a "file.txt" ); echo "${PIPESTATUS[0]}"
0

$> OUT=$( wget -q "http://budueba.com/net" | tee -a "file.txt" ); echo "${PIPESTATUS[-1]}"
0

Итак, мой вопрос - как я могу получить код выхода wget через tee и subshell?

Если это может быть полезно, моя версия bash 4.2.20.

Ответы [ 3 ]

16 голосов
/ 14 февраля 2012

Используя $(), вы (фактически) создаете подоболочку.Таким образом, экземпляр PIPESTATUS, на который вам нужно обратить внимание, доступен только внутри вашей подоболочки (то есть внутри $()), поскольку переменные среды не распространяются от дочерних процессов к родительским.

Вы можете сделать что-то подобное:

  OUT=$( wget -q "http://budueba.com/net" | tee -a "file.txt"; exit ${PIPESTATUS[0]} );
  echo $? # prints exit code of wget.

Подобного поведения можно добиться с помощью следующего:

  OUT=$(wget -q "http://budueba.com/net")
  rc=$? # safe exit code for later
  echo "$OUT" | tee -a "file.txt"
5 голосов
/ 17 марта 2017

Остерегайтесь этого при использовании local переменных:

local OUT=$(command; exit 1)
echo $? # 0

OUT=$(command; exit 1)
echo $? # 1
0 голосов
/ 02 ноября 2013

Сначала скопируйте массив PIPESTATUS.Любые операции чтения разрушают текущее состояние.

declare -a PSA  
cmd1 | cmd2 | cmd3  
PSA=( "${PIPESTATUS[@]}" )

Я использовал fifos для решения проблемы sub-shell / PIPESTATUS.См. bash pipestatus в команде backticked?
Я также нашел это полезным: bash script: как сохранить возвращаемое значение первой команды в конвейере?
и https://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another/70675#70675

...