Bash:通过管道将 stdout 和 stderr 捕获到变量中

Bash: Pipe stdout and catch stderr into a variable

是否可以将普通 stdout 进一步传输到另一个程序,但将 stderr 存储到变量中?

这是用例:

mysqldump database | gzip > database.sql

在这种情况下,我想捕获 mysqldump 生成的所有 errors/warnings 并将它们存储到一个变量中,但是正常的 stdout (即转储)应该继续传送到 gzip.

关于如何实现这个的任何想法?

您可以执行以下操作:

mysqldump database 2> dump_errors | gzip > database.sql
error_var=$( cat dump_errors )
rm dump_errors

在这里,mysqldump 的所有错误都被重定向到一个名为 'dump_errors' 的文件,标准输出通过管道传输到 gzip,后者又写入 database.sql

然后将 'dump_errors' 的内容分配给变量 'error_val',然后删除文件 'dump_errors'。


注意以下重定向:

$ sort 1> output 2> errors   # redirects stdout to "output", stderr to "errors"
$ sort 1> output 2>&1        # stderr goes to stdout, stdout writes to "output"
$ sort 2> errors 1>&2        # stdout goes to stderr, stderr writes to "errors"

$ sort 2>&1 > output         # tie stderr to screen, redirect stdout to "output"
$ sort > output 2>&1         # redirect stdout to "output", tie stderr to "output"

你可以这样做:

errors=$(mysqldump database 2>&1 > >(gzip > database.sql))

在这里,我使用进程替换让 gzip 使用 mysqldump 的输出作为标准输入。鉴于 the order of redirections (2>&1 before >)mysqldump 的标准错误现在应该用于命令替换。

正在测试:

$ a=$(sh -c 'echo foo >&2; echo bar' 2>&1 > >(gzip > foo))
$ gunzip < foo
bar
$ echo $a
foo