在 bash 脚本中抑制 stderr 消息

fea*_*ool 64 bash shell-script stderr

考虑以下(有点傻)脚本名称“test1.sh”:

#/bin/bash
#
sleep 10 &
echo sleep pid = $!
pkill sleep
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我不仅得到了 echo 的输出,还得到了 bash 在 stderr 上报告睡眠死亡的报告:

$ ./test1.sh
sleep pid = 3551
./test1.sh: line 5:  3551 Terminated              sleep 10
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我想抑制打印输出到 stderr。我知道我可以在命令行上完成,如下所示:

$ ./test1.sh 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

......但有没有办法从抑制其的脚本?(我知道我可以将它包装在第二个脚本中并让包装器重定向它,但一定有更简单的东西......)

Sco*_*ott 97

你是对的; pkill 没有生成消息,bash 是。你建议

$ ./test1.sh 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

是一个可能的解决方案。正如 UVV 指出的那样,脚本中的等效操作是

exec 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

这会将脚本的 stderr 重定向/dev/null 到此语句,直到它被更改回来。将其改回的笨拙方法包括

exec 2> /dev/tty
Run Code Online (Sandbox Code Playgroud)

它将 stderr 重定向到终端。这可能(但不一定)是它最初的位置。

或者

exec 2>&1
Run Code Online (Sandbox Code Playgroud)

这将 stderr 设置为与 stdout 相同,并且很可能是错误的。

更可靠的方法是

执行 3>&2
执行 2> /dev/null
(做一些你不想看到 stderr 的事情。) 
exec 2>&3

它将原始 stderr 保存在文件描述符 3 中,然后将其恢复。

其他抑制进程死亡通知的方法包括

exec 3>&2
exec 2> /dev/null
(do stuff where you don't want to see the stderr.)
exec 2>&3

(sleep 10 & pkill sleep) 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

仅更改分组命令的标准错误。


UVV*_*UVV 11

根据这个你可以做类似如下:

#!/bin/bash
exec 2>/dev/null
ls -al test
Run Code Online (Sandbox Code Playgroud)