小编Joe*_*nas的帖子

在代码“{ exec >/dev/null; } >/dev/null”中到底发生了什么?

当您重定向包含 exec 重定向的命令列表时,之后 exec >/dev/null 似乎不再应用,例如:

{ exec >/dev/null; } >/dev/null; echo "Hi"
Run Code Online (Sandbox Code Playgroud)

打印“嗨”。

我的印象是,{}除非它是管道的一部分,否则命令列表不被视为子shell,因此exec >/dev/null在我看来,它仍应应用于当前的 shell 环境中。

现在,如果您将其更改为:

{ exec >/dev/null; } 2>/dev/null; echo "Hi"
Run Code Online (Sandbox Code Playgroud)

没有预期的输出;文件描述符 1 仍然指向 /dev/null 以供将来的命令使用。这通过重新运行显示:

{ exec >/dev/null; } >/dev/null; echo "Hi"
Run Code Online (Sandbox Code Playgroud)

这不会给出任何输出。

我尝试制作一个脚本并跟踪它,但我仍然不确定这里到底发生了什么。

在这个脚本的每一点 STDOUT 文件描述符发生了什么?

编辑:添加我的 strace 输出:

read(255, "#!/usr/bin/env bash\n{ exec 1>/de"..., 65) = 65
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_GETFD)                       = 0
fcntl(1, F_DUPFD, 10)                   = 10
fcntl(1, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = …
Run Code Online (Sandbox Code Playgroud)

command-line shell bash io-redirection file-descriptors

16
推荐指数
3
解决办法
2980
查看次数