Tcp
nc -l 在後台立即關閉 (nc -l 1234 &)
當我把這個
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 上,nc和nmap-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具有相同屬性的文件。如果它是互動式外殼,則不需要發生這種情況。在所有情況下,標準輸入的顯式重定向應覆蓋此活動。
當客戶端通過 port
telnet
建立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 &'