在我的脚本中,我有一个复杂的命令,可以在stdout
和上生成输出stderr
。我需要将两者捕获到单独的变量中:
#!/bin/sh
A=$(command)
如何“捕获”stderr
到变量中B
?
我尝试了 和 的一些变体,2>&1
但read
不起作用:
A=$(some_command) 2>&1 | read B
echo $B
或者
{ OUT="$(command)" 2>&1 | read B ; }
echo $B
唯一有效的方法是重定向stderr
到临时文件,然后将其读回。但这似乎是一个肮脏的黑客行为。有没有办法不使用临时文件来做到这一点?
更新
澄清一下,stdout
和stderr
都是多行输出。
答案1
老实说,使用文件可能是最简单的方法。但是,让我们在这里做出一些假设,假设您想要stdout
作为单行变量,并且不关心stderr
是否为 1 行(或者也将其展平)。然后让我们使用一个简单的脚本进行测试 - 其中“2”转到stderr
标准输出,其他行转到标准输出:
> cat outerr.sh
echo 1
echo 2 >&2
echo 3
> ./outerr.sh
1
2
3
> ./outerr.sh 2>/dev/null
1
3
然后你可以做类似的事情:
(echo $(./outerr.sh) # Collect and flatten the stdout output
# Meanwhile stderr flows through the pipe
) 2>&1|{
read err # This assumes stderr is one line only
read out
echo "err=$err"
echo "out=$out"
}
或者如果 stderr 可以是多行的,那么
(echo $(./outerr.sh) # Collect and flatten the stdout output
# Meanwhile stderr flows through the pipe
) 2>&1|tac|{ # reverse the output so the stdout line comes first
read out
err=$(tac) # reverse lines again, back to the original line order
echo "err=$err"
echo "out=$out"
}
带输出
err=2
out=1 3
如果stdout
需要保留行,您可以嵌入 \n 换行符,或者再次返回使用文件。