Tcp

nc -l 在後台立即關閉 (nc -l 1234 &)

  • March 20, 2019

當我把這個

nc -l 12345 >nc_out

在 shell 腳本中,執行它,然後使用 telnet 從其他 shell 連接,它允許我輸入一些文本並將其結束在nc_out中。

但是如果我在後台啟動 nc (我想稍後從同一個腳本啟動 telnet):

nc -l 12345 >nc_out &

連接立即關閉:

# telnet localhost 12345
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host
#

將 nc_out 文件留空。

這是為什麼?如何讓 nc 正常接受連接?


筆記:

  • 在 RHEL 和 Fedora 上,ncnmap-ncat 都以這種方式執行,但 Debian 的nc-traditional確實接受連接並讓我將數據保存到 nc_out。
  • 如果我從相同的腳本或不同的(SSH)會話呼叫 telnet 並不重要,行為是相同的
  • 我還按照@Hauke Laging 的建議使用 strace 執行命令,並將strace 輸出發佈到 Pastebin

在禁用作業控制的非互動式 shell 中執行的後台命令(在 shell 腳本中就是這種情況)stdin/dev/null.

sh -c 'nc -l 12345 1>nc_out & lsof -p $!'

POSIX.1-2008開始:

2.Shell 命令語言

$$ … $$ 非同步列表

如果命令被控制操作符 (’&’) 終止,shell 將在子 shell 中非同步執行命令。這意味著 shell 在執行下一個命令之前不應等待命令完成。

在後台執行命令的格式是:

command1 & [command2 & ... ]

在執行任何顯式重定向之前,非同步列表的標準輸入應被視為分配給與 /dev/null具有相同屬性的文件。如果它是互動式外殼,則不需要發生這種情況。在所有情況下,標準輸入的顯式重定向應覆蓋此活動。

當客戶端通過 porttelnet建立localhost與已經執行的命令的連接時,後台命令似乎在其標準輸入上檢測到 EOF 並開始其關閉過程,因為它是強制從 /dev/null 讀取的。命令 ( )的返回值為零表示文件結束。nc``12345``nc``read``man 2 read

# strace output (from http://pastebin.com/YZHW31ef)
14:32:26 read(0, "", 2048)              = 0
14:32:26 shutdown(4, 1 /* send */)      = 0

以下是一些保持telnet執行和通信的解決方案nc

sh -c 'nc -l 12345 0<&0 1>nc_out &'
sh -c 'nc -l 12345 0<&- 1>nc_out &'
sh -c 'tail -f /dev/null | nc -l 12345 1>nc_out &'
sh -c 'rm -f fifo; mkfifo fifo; exec 3<>fifo; nc -l 12345 0<fifo 1>nc_out &'

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