![OS X ログインフック - nc が理由もなく途中で終了する](https://rvso.com/image/1438700/OS%20X%20%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%83%95%E3%83%83%E3%82%AF%20-%20nc%20%E3%81%8C%E7%90%86%E7%94%B1%E3%82%82%E3%81%AA%E3%81%8F%E9%80%94%E4%B8%AD%E3%81%A7%E7%B5%82%E4%BA%86%E3%81%99%E3%82%8B.png)
使用しようとしていますログインフック大量のデータをダウンロードしようとしましたが、原因がはっきりしないまま nc が途中で終了してしまうことが原因であることが判明しました。以下は簡略化されたテスト スクリプトです。
#!/bin/bash exec > /tmp/lhook.out.txt 2> /tmp/lhook.err.txt nc -v server 4444 > /tmp/nc-test echo "Exit value: $?"
サーバー上で、 のような単純な nc リスナーを実行するとecho "Hello world. | nc -l 4444
、転送は正常に機能します。 しかし、 のような大きなファイルを転送する場合、nc -l 4444 < /path/to/some/large.file
クライアントは小さな部分 (2kiB の場合もあれば、約 250 kiB の場合もあります) のみを転送します。 報告される終了値は 0 です。
ああ、もちろん、ユーザー セッション内の Terminal.app で実行される同じスクリプトは正常に動作します。
デバッグを手伝ったり、何が起こっているのか説明したり、解決策を提供したりしてくれる人はいますか?
編集: dtruss
netcat のシステムコールをスヌープしてみたところ、次のような結果が得られました:
157/0x4c6: write(0x1, "j,\350\037\376\377\377\203\304$f\211F\016\350&f\004\0", 0x400) = 1024 0
157/0x4c6: select(0x5, 0x7FFF53A87B40, 0x0, 0x0, 0x0) = 1 0
157/0x4c6: read(0x4, "\001u\374)u\f\215\f6\203\304\020\003\331\001\b\353\035\017\267\003\213\027P\213\317\377R\004\271\377\377\0", 0x400)
= 1024 0
157/0x4c6: write(0x1, "\001u\374)u\f\215\f6\203\304\020\003\331\001\b\353\035\017\267\003\213\027P\213\317\377R\004\271\377\377\0", 0x400)
= 1024 0
157/0x4c6: select(0x5, 0x7FFF53A87B40, 0x0, 0x0, 0x0) = 1 0
157/0x4c6: read(0x4, "\0", 0x400) = 0 0
157/0x4c6: shutdown(0x4, 0x0, 0x0) = -1 Err#57
157/0x4c6: close(0x4) = 0 0
157/0x4c6: close(0x3) = 0 0
157/0x4c6: close(0x3) = -1 Err#9
何らかの理由で、カーネルがさらにデータを待つ代わりに nc EOF を発行しているのではないかと思います。
答え1
なんと恥ずかしい見落としでしょう... :-(
nc
は、stdin から EOF を読み取ると終了します。データを受信するクライアントは、非対話型シェルで LoginHook スクリプトを実行し、nc
おそらく の stdin 記述子を に送信します/dev/null
。そこから EOF を読み取るとすぐに終了します。
修正は簡単です。-d
受信側にスイッチを供給するだけです。これにより、netcat のどちらのバージョン (BSD または Linux) も stdin を読み取れなくなり、転送は問題なく完了します。