Получить код выхода из подоболочки через трубы

Как я могу получить код завершения wget из процесса подоболочки?

Таким образом, главная проблема заключается в том, что $? равно 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 и подоболочку?

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

Ответ 1

Используя $(), вы (эффективно) создаете подоболочку. Таким образом, экземпляр 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"

Ответ 2

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

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

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

Ответ 3

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

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

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