Stdout

如何擷取既不發送到 stdout 也不發送到 stderr 的輸出?

  • September 6, 2021

據我所知,該命令生成的某些輸出/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來擷取它通常會發送到終端的所有輸出?

取決於程序做什麼。除了標準輸出(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 只是作為一個地方 ho"..., 44) = 44
...

因此,除了 stdout 和 stderr 的任何重定向之外,您還可以通過將 stdin (fd 0) 重定向到某個文件來重定向該部分消息,例如0>somefile(或抑制它)。/dev/null

類似的重定向< /dev/tty還可以通過為程序提供顯式只讀 fd 來阻止輸出。(不過,程序會因為呼叫而出錯。)在 Linux上,如果原始標準輸入連接到終端write(),您甚至可以使用相同的結果。< /dev/stdin

如果使用了某些程序/dev/tty,則擷取輸出會更加困難。如果可用,可以使用類似的東西setsid在沒有控制終端的情況下啟動程序,這意味著打開/dev/tty會失敗。(好吧,這就是它在 Linux 上所做的。)

引用自:https://unix.stackexchange.com/questions/667632