nc は、OS X でサーバーが切断されるのを待ちません。

nc は、OS X でサーバーが切断されるのを待ちません。

ncOS X Mavericksで、クライアントがソケットを開いたままにし、サーバーがソケットから切断されるまでデータを読み取るようにする方法は?

データをサーバーに送信し、nc応答を使用してこれを実行したいと思います。問題は、ncサーバーからの応答を待たずにデータを送信した後にソケットを切断することです。

これによりデータが記録され終了します。

$ echo "my instruction here" | nc 127.0.0.1 $MY_PORT

これにより、データを書き込んだ後にサーバーが切断されても終了しません。

$ cat <(echo "my instruction here") - | nc 127.0.0.1 $MY_PORT

OS X Mavericksのマニュアルページには、リクエストを送信してレスポンスを印刷する次のncHTTP GETがありますが、機能しません。ただ要求を送信し、サーバーからの応答を待たずに終了します。マニュアルページの情報が間違っていると思いますか?

$ echo -n "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80

答え1

ncのデフォルトの動作は、stdinが閉じられたときに接続を閉じることです。変更するには、Linuxで-qオプション(たとえば-q -1)を使用できます。OS Xではおそらく同じです。詳しくはマニュアルページをご覧ください。

編集:OS X ncは-qスイッチなどをサポートしていないようです。この場合、次の手順を実行してstdinが閉じられないようにする必要があります。

(エコ「foo」、睡眠100000)|

答え2

リスニングnc(サーバー)が閉じると、クライアントncも終了します。

Mac OS Xではopen -a 'Activity Monitor'これを確認できます。

例は中断さnc & catれず、nc読み取りcatと書き込みのためにstdinとstdoutを開いたままにします。

ただし、catリスナーが閉じてパイプに書き込もうとすると、エラーが発生して終了します。ncSIGPIPEcat

# cat & SIGPIPE test
(sleep 1; echo hi) | 
   (trap 'echo "received signal $(($? - 128))" 1>&2' EXIT; cat) | :

kill -l 13
man bash | less -p 'EXIT STATUS'
man bash | less -Ip '128\+n'

Niklas Berglundの回避策のnc代わりに、中断されたコマンドを含むプロセスグループ全体を終了するためにクライアント出口をキャプチャすることが可能ですcat

# console 1
# ctrl-c will "kill 0" entire process group sh -c '...'
nc -l 8080  

# console 2
# script command (FreeBSD version) will implicitly run: man 2 setsid
# kill 0 will therefore only kill the entire process group sh -c '...' 
# run in a script kill 0 would otherwise kill the entire script
# cf. also https://github.com/jerrykuch/ersatz-setsid 
script -q /dev/null sh -c '
(echo "my instruction here"; cat) | (trap "kill 0" EXIT; nc 127.0.0.1 8080)
'

答え3

解決策はソケットに書き込むことです。ncデータを書き込めなくなったら終了します。

(echo -ne "GET / HTTP/1.0\r\n\r\n"; (while true; do echo -e "\n"; sleep 1; done)) | nc example.com 80

ncncソケットに書き込めないため、終了するまで毎秒空白行を送信しますnc

このソリューションを案内してくれたSteffen Ullrichの回答とコメントに感謝します。

関連情報