我想执行一个命令(比如说 ls
)和 sed
的输出,然后将stdout保存到一个变量中,像这样。
OUT=$(ls | sed -n -e 's/regexp/replacement/p')
在这之后,如果我试图访问 $PIPESTATUS
数组,我只得到 0
宛如 $?
). 那么,我如何才能同时获得 $PIPESTATUS
以及捕获整个管道命令的stdout?
请注意。
ls | sed -n -e 's/regexp/replacement/p'
),我在 $PIPESTATUS
(像 0 0
)OUT=$(ls)
),我得到的预期是 单一 退出状态 $PIPESTATUS
宛如 $?
)P.S. 我知道,我可以运行2次命令(第一次捕获stdout,第二次访问 $PIPESTATUS
而不使用命令替换),但是有什么方法可以在一次执行中同时获得这两个命令?
你可以这样做。
用一个临时文件来传递PIPESTATUS。
tmp=$(mktemp)
out=$(pipeline; echo "${PIPESTATUS[@]}" > "$tmp")
PIPESTATUS=($(<"$tmp")) # Note: PIPESTATUS is overwritten each command...
rm "$tmp"
使用一个临时文件来传递PIPESTATUS。out
.
tmp=$(mktemp)
pipeline > "$tmp"
out=$(<"$tmp"))
rm "$tmp"
将输出与pipestatus交错。例如,从最后一个换行符到最后的部分保留给PIPESTATUS。为了保留原始的返回状态,我认为需要一些临时变量。
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
注意: