Proc

查看stdin的內容

  • January 15, 2017

我正在嘗試調試一個可以通過標準輸入接收命令的 Linux 應用程序,能夠看到寫入標準輸入的所有內容非常有用。

我的第一種方法是執行sudo cat /proc/$pid/fd/0,但事實證明這是一種無效的方法,因為cat我的程序和我的程序都在嘗試使用該文件描述符的內容,並且只有一個程序可以贏得比賽。

另一種方法是使用tail,但由於此處列出的原因,這不起作用。

我可以輕鬆地將調試日誌記錄添加到我的應用程序中,這將解決問題,但我很想知道是否有我缺少的更通用的方法。

strace?

下面的例子。啟動一個 cat 程序,該程序正在讀取標準輸入並寫入 /tmp/foofile。找到pid,strace它。並且在原來的貓視窗中,輸入一些文字,嘿嘿。

# cat >/tmp/foofile


# ps -ef|grep cat
steve     2134  1801  0 22:25 pts/2    00:00:00 cat
# strace -fp 2134
Process 2134 attached
read(0, "test\n", 65536)                = 5
write(1, "test\n", 5)                   = 5
read(0,

要從文件描述符 0 中提取讀取:

strace -fp 2134 -e trace=read -o "|grep read.0,"

在 linux 上,您可以將應用程序的文件描述符作為/dev/fd/[0-9]. 您絕對可以對命名文件和輸入流執行的操作是tee對該文件標準輸出的輸入。因此,當我發現自己處於您的情況時*(就像我經常做的那樣),我通常會做*的事情是tee輸入到我的閱讀應用程序和/dev/fd/2-stderr。

像這樣:

seq 10 | tee /dev/fd/2 | wc -c
1
2
3
4
5
6
7
8
9
10
21

當然,即使你不在一個 linux 系統上,同樣的事情也可以便攜地完成——如果在某些情況下不太具體的話——只需做...| tee /dev/tty | ...

如果您在說stdin *(如您的連結所示)*時談論的是終端,那麼您可能仍然會做同樣的事情,儘管由於核心的行緩衝,它可能會變得更加棘手。因此,在這種情況下,我會做的是tty通過將我的命令包裝進去來記錄所有 i/ luito——因為我發現它在兩者中更方便——儘管script也可以以大致相同的方式工作。

luit可能已經安裝在您的系統上 - 它通常與 / 打包xterm- 它是一個非常簡單的 cli 工具,旨在進行 UTF-8 翻譯*(該功能可能完全通過 cli 開關禁用,但我從來沒有找到理由這樣做)*對於不理解它的終端應用程序。

它的工作原理是在目前 tty 層下將自己的 pty(它擁有主 fd)分層並將所有 i/o 從目前會話複製到其子層,在那裡它執行您請求的應用程序。因為它擁有主端,所以它可以輕鬆地複制它在其他地方讀取/寫入的所有 i/o,並且它提供了一種方便的方法來要求它這樣做:

luit -olog /dev/fd/2 sh -c 'read var; echo "$var"'
eecchhoo  tthhiiss  vvaarr??????

echo this var???
echo this var???

如您所見,將所有終端輸入luit記錄到其命名-olog文件中。

在這種情況下,使用/dev/fd/2幾乎沒有那麼有用——因為所有的 i/o 都會在同一個地方結束兩次。我通常更喜歡打開第二個終端,使用tty命令查詢其名稱,並將該/dev/pts/[0-9]名稱用作luit/script的命名輸出文件 - 這會將所有 i/o 同時復製到兩個終端 - 所以我可以在一個終端上閱讀/查看它,並與之互動。tee在大多數情況下可以用來做同樣的事情,但它通常沒有 pty 的 master 端推薦它的優勢。

如果您的目的正如您所說的那樣 - 複製所有流程的輸入以供您查看 - 那麼您可能最好專注於輸入。strace對很多事情都很有用,但是如果您想獲得典型行為的準確報告,那麼有理由認為您應該在收集報告時盡可能少地修改該行為。換句話說,如果你想要輸入,複製輸入,不要插入一個調試父程序,它會-TRAP在每次進行系統呼叫時暫停你的程序。

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