我正在编写一个备份数据库的脚本。我有以下几行:
mysqldump --user=$dbuser --password=$dbpswd \
--host=$host $mysqldb | gzip > $filename
我想将stderr分配给变量,以便它会向我发送一封电子邮件,让我知道如果出现问题会发生什么。我找到了将stderr重定向到stdout的解决方案,但我不能这样做,因为stdout已经被发送(通过gzip)到一个文件。如何将stderr分别存储在变量$ result中?
答案 0 :(得分:76)
尝试将stderr重定向到stdout并使用$()
来捕获它。换句话说:
VAR=$((your-command-including-redirect) 2>&1)
由于你的命令在某处重定向stdout,它不应该干扰stderr。可能有一种更清晰的方式来编写它,但这应该有效。
修改强>
这确实有效。我测试了它:
#!/bin/bash
BLAH=$((
(
echo out >&1
echo err >&2
) 1>log
) 2>&1)
echo "BLAH=$BLAH"
将打印BLAH=err
,文件log
包含out
。
答案 1 :(得分:17)
对于Bash中的任何通用命令,您可以执行以下操作:
{ error=$(command 2>&1 1>&$out); } {out}>&1
正常输出正常显示,stderr的任何内容都在$ error中捕获(当使用它来保留换行符时将其引用为“$ error”)。要将stdout捕获到文件,只需在末尾添加重定向,例如:
{ error=$(ls /etc/passwd /etc/bad 2>&1 1>&$out); } {out}>&1 >output
打破它,从外面读,它:
答案 2 :(得分:4)
您可以在将stdout引用重定向到另一个文件编号(例如3)之前将其保存,然后将stderr重定向到:
result=$(mysqldump --user=$dbuser --password=$dbpswd \
--host=$host $mysqldb 3>&1 2>&3 | gzip > $filename)
所以3>&1
会将文件号3重定向到stdout(注意这是在stdout被管道重定向之前)。然后2>&3
将stderr重定向到文件号3,现在与stdout相同。最后,stdout被送入管道重定向,但这不会影响文件编号2和3(注意,从gzip重定向stdout与mysqldump命令的输出无关)。
编辑:更新了命令以从mysqldump
命令而不是gzip
重定向stderr,我的第一个答案太快了。
答案 3 :(得分:0)
dd
写了stdout和stderr:
$ dd if=/dev/zero count=50 > /dev/null
50+0 records in
50+0 records out
这两个流是独立的,可单独重定向:
$ dd if=/dev/zero count=50 2> countfile | wc -c
25600
$ cat countfile
50+0 records in
50+0 records out
$ mail -s "countfile for you" thornate < countfile
如果你真的需要一个变量:
$ variable=`cat countfile`