無法使用nohup和socat捕獲遠端客戶端數據

無法使用nohup和socat捕獲遠端客戶端數據

我需要捕獲socat在遠端伺服器上運行的詳細和調試輸出。

socat在前台運行時我可以實現上述目標:

$ socat -x -d -d -d tcp-l:8080,bind=0.0.0.0,fork,reuseaddr - 2>stderr.log >stdout.log

然而,如果在背景運行stdout.log上述內容,則不會收到任何輸出nohup:

$ nohup socat -x -d -d -d tcp-l:8080,bind=0.0.0.0,fork,reuseaddr - 2>stderr.log >stdout.log &

這是stderr.log我啟動nohup socat上面的版本後的情況:

nohup: ignoring input
2024/03/24 20:06:22 socat[28360] I socat by Gerhard Rieger and contributors - see www.dest-unreach.org
2024/03/24 20:06:22 socat[28360] I This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/)
2024/03/24 20:06:22 socat[28360] I This product includes software written by Tim Hudson ([email protected])
2024/03/24 20:06:22 socat[28360] I setting option "bind" to "0.0.0.0"
2024/03/24 20:06:22 socat[28360] I setting option "fork" to 1
2024/03/24 20:06:22 socat[28360] I setting option "so-reuseaddr" to 1
2024/03/24 20:06:22 socat[28360] I socket(2, 1, 6) -> 5
2024/03/24 20:06:22 socat[28360] W ioctl(5, IOCTL_VM_SOCKETS_GET_LOCAL_CID, ...): Inappropriate ioctl for device
2024/03/24 20:06:22 socat[28360] I starting accept loop
2024/03/24 20:06:22 socat[28360] N listening on AF=2 0.0.0.0:8080

接下來我8080從 netcat 連接到端口,

$ nc localhost 8080

這就是stderr.log捕獲的內容:

2024/03/24 20:06:59 socat[28360] I accept(5, {2, AF=2 127.0.0.1:37910}, 16) -> 6
2024/03/24 20:06:59 socat[28360] N accepting connection from AF=2 127.0.0.1:37910 on AF=2 127.0.0.1:8080
2024/03/24 20:06:59 socat[28360] I permitting connection from AF=2 127.0.0.1:37910
2024/03/24 20:06:59 socat[28360] N forked off child process 28563
2024/03/24 20:06:59 socat[28360] I close(6)
2024/03/24 20:06:59 socat[28360] I still listening
2024/03/24 20:06:59 socat[28360] N listening on AF=2 0.0.0.0:8080
2024/03/24 20:06:59 socat[28563] I just born: child process 28563
2024/03/24 20:06:59 socat[28563] I close(4)
2024/03/24 20:06:59 socat[28563] I close(3)
2024/03/24 20:06:59 socat[28563] I just born: child process 28563
2024/03/24 20:06:59 socat[28563] I close(5)
2024/03/24 20:06:59 socat[28563] N reading from and writing to stdio
2024/03/24 20:06:59 socat[28563] I resolved and opened all sock addresses
2024/03/24 20:06:59 socat[28563] N starting data transfer loop with FDs [6,6] and [0,1]
2024/03/24 20:06:59 socat[28563] E read(0, 0x60485184f000, 8192): Bad file descriptor
2024/03/24 20:06:59 socat[28563] N exit(1)
2024/03/24 20:06:59 socat[28563] I shutdown(6, 2)
2024/03/24 20:06:59 socat[28360] N childdied(): handling signal 17
2024/03/24 20:06:59 socat[28360] I childdied(signum=17)
2024/03/24 20:06:59 socat[28360] I childdied(17): cannot identify child 28563
2024/03/24 20:06:59 socat[28360] I waitpid(): child 28563 exited with status 1
2024/03/24 20:06:59 socat[28360] I waitpid(-1, {}, WNOHANG): No child processes
2024/03/24 20:06:59 socat[28360] I childdied() finished

接下來,我在 netcat 終端機中輸入一些文本,然後按 ENTER。

然而,問題是:不僅 netcat 退出,我stdout.log也看不到我輸入的文本

除了闡明這裡發生的情況之外,有人還可以建議如何捕獲nohup'ed的 stderr 和 stdoutsocat嗎?本質上,我需要捕獲遠端套接字客戶端發送到的所有資料-v-d -d -d輸出。stderr.logstdout.log

答案1

解釋

這是關於 的 stdin 的socat

對於在背景運行的命令&,基本上有兩種可能性:

  • 如果在 shell 中停用作業控制(這是腳本的預設設定),則命令的 stdin 應重定向(在執行任何明確重定向之前)到/dev/null或等效檔案。

  • 如果在 shell 中啟用了作業控制(這是互動式使用中的預設設定),則命令的 stdin 就是您所期望的,因此它可能是終端。如果是終端,則後台指令無法竊取其中的輸入;如果它嘗試,就會收到 SIGTTIN。您仍然可以使用fg和將命令帶到前台然後它可以從終端讀取。

nohup其本身會將標準流重定向到遠離終端的位置,因此即使在後一種情況下,socat當您嘗試從其標準輸入讀取時,您在後台或其任何子/線程/其他內容也會立即獲得EOF 條件(或某些錯誤)。

您應該能夠使用 like 快速傳遞數據echo message | nc localhost 8080socat處理此特定連接應該在終止之前收到訊息,因為其標準輸入上有 EOF。


解決方案

如果您不希望連接由於 的 stdin 上的 EOF 而終止socat,請告訴工具不要從此位址讀取。從man 1 socat

-u使用單向模式。第一個位址僅用於讀取,第二個位址僅用於寫入[...]。

-U反向使用單向模式。第一個位址僅用於寫入,第二個位址僅用於讀取。

在你的情況下-(意思是STDIO)是第二個地址,所以你需要-u

nohup socat -u -x -d -d -d tcp-l:8080,bind=0.0.0.0,fork,reuseaddr - 2>stderr.log >stdout.log &

相關內容