如何捕获既不发送到 stdout 也不发送到 stderr 的输出?

如何捕获既不发送到 stdout 也不发送到 stderr 的输出?

据我所知,该命令生成的一些输出/usr/bin/modulecmd既不发送到 stdout 也不发送到 stderr,如以下示例所示:

% /usr/bin/modulecmd bash help null >/dev/null 2>&1
        This module does absolutely nothing.
        It's meant simply as a place holder in your
        dot file initialization.

        Version 3.2.9

有没有什么方法可以调用命令(例如 /usr/bin/modulecmd),以便其所有输出都转到 stdout 或 stderr?或者,是否有某种方法可以让代码调用/usr/bin/modulecmd捕获全部它通常会发送到终端的输出?

答案1

取决于程序的作用。除了标准输出 (fd 1) 和错误 (fd 2) 之外,标准输入当程序在没有重定向的情况下从终端启动时,(fd 0) 通常也以读写方式打开,并且可用于写入输出。另一种选择是显式 open /dev/tty,这会提供一个连接到进程控制终端的新 fd。

modulecmd由于某种原因使用标准输入。运行strace它,我们看到它将标题行写入原始的 fd 2,然后(在一些不涉及 fd 0 的不相关的 fd 杂耍之后)将 fd 0 (stdin) 复制到 fd 2,并在那里打印描述。

...
write(2, "\n------------ 模块特定 Hel"..., 70) = 70
...
[其他fd的无关洗牌]
...
重复(0) = 2
write(2, "\t这个模块绝对不会"..., 37) = 37
写(2, "\r\n", 2) = 2
write(2, "\t它的意思只是作为一个地方"..., 44) = 44
...

因此,除了 stdout 和 stderr 的任何重定向之外,您还可以通过将 stdin (fd 0) 重定向到某个文件来重定向消息的该部分,例如0>somefile(或抑制它)。/dev/null

类似的重定向< /dev/tty还可以通过为进程提供显式只读 fd 来阻止输出。 (不过,程序会收到调用错误。)在 Linux 上,如果原始标准输入连接到终端,write()您甚至可以得到相同的结果。< /dev/stdin

如果使用某些程序/dev/tty,捕获输出会更困难。如果有的话,类似的东西setsid可以用来在没有控制终端的情况下启动程序,这将意味着打开/dev/tty失败。 (好吧,这就是它在 Linux 上所做的事情。)

答案2

我认为这个问题的答案是“" 原因如下:您只能重定向命令启动之前存在的输出。也就是说:如果命令打开新的输出,您无法通过重定向来阻止它。

相关内容