在我的 bash 脚本中,我读入了一组看起来像这样的行
arg $PROG arg arg
我希望能够运行该行,将 STDERR 捕获为变量,并防止将 STDOUT 或 STDERR 打印到屏幕上。到目前为止,这是我的解决方案,但错误变量始终为空。
$PROG=/c/Program1
{ error=$($(eval $line) 2>&1 1>&$out); } {out}>&1
echo $error
请详细解释解决方案。我是 bash shell 脚本的新手,正在尝试学习。
对于像这样同时打印到 stdout 和 stderr 的命令:
mycommand () { echo "stdout"; echo "stderr" >&2; }
如果我正常发出,我会看到所有输出:
$ mycommand
stdout
stderr
我可以将 stdout 或 stderr 重定向到 /dev/null
所以它不会被打印出来:
$ mycommand >/dev/null # Equivalent to 1>/dev/null
stderr
$ mycommand 2>/dev/null
stdout
如果我只想捕获 stderr,我首先必须将 stderr 重定向到 stdout out 当前指向的位置,然后将 stdout 重定向到 /dev/null
:
error="$(2>&1 1>/dev/null mycommand)"
现在 error
只包含来自 stderr 的输出:
$ echo "$error"
stderr
线上的位置并不重要,但重定向的顺序很重要,所以这具有相同的效果:
error="$(mycommand 2>&1 1>/dev/null)"
但这不是:
error="$(1>/dev/null 2>&1 mycommand)"
最后一条命令会将 stdout 和 stderr 都重定向到 /dev/null
,而 error
将为空。
Bash Hackers Wiki 上有一个很好的重定向资源.
关于您尝试过的一些建议:
- 赋值要求不能在参数名中使用
$
,所以应该是PROG=/c/Program1
而不是$PROG=/c/程序 1
。
- 不鼓励使用大写变量名,因为它们更可能与环境变量发生冲突。
- 在 99% 的情况下,有一个解决方案可以避免
eval
,请参阅 BashFAQ/048为什么这是个好主意。