bash - 捕获 stderr,但不捕获 stdout

标签 bash shell

<分区>

在我的 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为什么这是个好主意。

关于bash - 捕获 stderr,但不捕获 stdout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36522509/

相关文章:

php - exec、system 和 shell_exec PHP 函数中的命令字符串不能超过 8175 个字符

bash - 如何将带双引号的空字符串传递给 bash 脚本?

python - 将 Django 应用程序部署到 Elastic Beanstalk 时出现内部服务器错误 500

bash - 如果失败,在 Bash 中执行一行而不中止?

git - 推送到gitlab时要求输入密码?

unix - 找出 POSIX 系统上是否存在命令

linux - 如何在 bash 中使用路径名和重新排序的序列批量重命名多个图像?

linux - 递归复制特定文件

linux - shell 脚本无法使用 grep 值设置环境变量

linux - 具有多个变量(语句)的循环