通过管道从子shell获取退出代码

时间:2012-02-14 13:36:38

标签: bash pipe exit-code tee subshell

如何从子shell进程中获取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和子shell获取tee退出代码?

如果它有用,我的bash版本为4.2.20

3 个答案:

答案 0 :(得分:15)

通过使用$(),您(有效地)创建子shell。因此,您需要查看的PIPESTATUS实例仅在子shell内(即$()内)可用,因为环境变量不会从子进程传播到父进程。

你可以这样做:

  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"

答案 1 :(得分:5)

使用local变量时请注意这一点:

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

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

答案 2 :(得分:0)

首先复制PIPESTATUS数组。任何读取都会破坏当前状态。

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

我用fifos来解决子shell / PIPESTATUS问题。看到 bash pipestatus in backticked command?
我也发现这些有用: bash script: how to save return value of first command in a pipeline?
https://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another/70675#70675