Bash 捕获stdout到变量并获取前台管道的退出状态
我想执行一个命令(比如说Bash 捕获stdout到变量并获取前台管道的退出状态,bash,shell,pipe,stdout,exit-code,Bash,Shell,Pipe,Stdout,Exit Code,我想执行一个命令(比如说ls)和sed它的输出,然后将stdout保存到一个变量,如下所示 OUT=$(ls | sed -n -e 's/regexp/replacement/p') 在此之后,如果我尝试访问数组,则只会得到0(这与$?相同)。那么,如何获取$PIPESTATUS以及捕获整个piped命令的stdout呢 注: 如果我只执行那些管道命令而没有捕获stdout(比如ls | sed-n-e's/regexp/replacement/p'),我会在$PIPESTATUS中获得预
ls
)和sed
它的输出,然后将stdout保存到一个变量,如下所示
OUT=$(ls | sed -n -e 's/regexp/replacement/p')
在此之后,如果我尝试访问数组,则只会得到0
(这与$?
相同)。那么,如何获取$PIPESTATUS
以及捕获整个piped命令的stdout呢
注:
- 如果我只执行那些管道命令而没有捕获stdout(比如
),我会在ls | sed-n-e's/regexp/replacement/p'
中获得预期的退出状态(比如$PIPESTATUS
)0
- 如果我使用并捕获stdout(如
)只执行单个命令(不使用管道传输多个命令),我将在OUT=$(ls)
中获得预期的单个退出状态(与$PIPESTATUS
相同)$?
$PIPESTATUS
,而不使用命令替换),但是有没有办法在一次执行中同时获得这两个命令?您可以:
tmp=$(mktemp)
out=$(pipeline; echo "${PIPESTATUS[@]}" > "$tmp")
PIPESTATUS=($(<"$tmp")) # Note: PIPESTATUS is overwritten each command...
rm "$tmp"
out=$(pipeline; tmp=("${PIPESTATUS[@]}") ret=$?; echo $'\n' "${tmp[@]}"; exit "$ret"))
pipestatus=(${out##*$'\n'})
out="${out%$'\n'*}"
out="${out%%$'\n'}" # remove trailing newlines like command substitution does
通过以下方式进行测试:
out=$(false | true | false | echo 123; echo $'\n' "${PIPESTATUS[@]}");
pipestatus=(${out##*$'\n'});
out="${out%$'\n'*}"; out="${out%%$'\n'}";
echo out="$out" PIPESTATUS="${pipestatus[@]}"
# out=123 PIPESTATUS=1 0 1 0
- 导出的变量应保留按约定使用的大写变量
out=$(false | true | false | echo 123; echo $'\n' "${PIPESTATUS[@]}");
pipestatus=(${out##*$'\n'});
out="${out%$'\n'*}"; out="${out%%$'\n'}";
echo out="$out" PIPESTATUS="${pipestatus[@]}"
# out=123 PIPESTATUS=1 0 1 0