名前付きパイプからデータを読み取るTCPサーバーとしてnetcatを使用したいと思います。そのために、私は次のことをしました。
ステップ1。パイプラインを作成してソースサーバーとして使用する
mkfifo /tmp/all.pipe
nc -k -l 8080 < /tmp/all.pipe
ステップ2。常にデータを読み取るクライアントを作成します。
while true; do
sleep 1;
echo "Check connection";
while IFS= read -r line; do
printf "$line";
done < /dev/tcp/localhost/8080;
done
ステップ3。パイプにいくつかのデータを書き込む:
echo "hello" > /tmp/all.pipe
この手順3を実行した後、クライアントの出力は次のようになります。
...
bash: connect: Connection refused
bash: /dev/tcp/localhost/8080: Connection refused
Check connection
bash: connect: Connection refused
bash: /dev/tcp/localhost/8080: Connection refused
Check connection
hello
ただし、手順3をやり直しても出力は変わりません。接続はまだ有効になっていますが、新しいデータがパイプからncに転送され、クライアントに転送されないため、これが発生しているようです。なぜ?それを達成するために何ができますか?
ベストアンサー1
上:
nc -k -l 8080 < /tmp/all.pipe
シェルは開こうとします/tmp/all.pipe
が、まだ書き込み用に名前付きパイプを開いたプロセスがないため停止します。
nc
まだ起動していないので、次bash
の理由を説明します。接続が拒否されました。そこに接続しようとしたとき。
するとき
echo "hello" > /tmp/all.pipe
その後、最初のコマンドがロック解除されます。これでパイプがインスタンス化されました。
その後、そこに書き込んでecho
終了hello\n
します。この時点で、パイプの書き込み端が閉じられ、nc
ファイルの終わりが標準入力に表示されます。cat
代わりに を使用すると終了nc
しcat
ます。
ただし、nc
標準出力はこの時点で依然として端末に到着し、TCP接続はまだアクティブであるため、一方の端が入力端に到達しても続行されます。たとえば、bash
そのソケットに何かを送信すると、stdoutに表示されます。nc
2番目の操作を実行すると、パイプのfdがまだ閉じていないecho something > /tmp/all.pipe
ため(少なくともUbuntu、YMMVパッケージの場合)、再びオンラインになるのと同じパイプを通過しましたが、放棄しました。後で読むと、早くeofに達しました。nc
nc
netcat-openbsd
nc
ここで最も簡単なのは、パイプの入力を読み取り+書き込みモードで開いて、即座にnc
インスタンス化され、nc
寿命の間常に維持されるようにすることです。
これを行うには、コマンドラインを<
次のように置き換えます。<>
nc
nc -k -l 8080 <> /tmp/all.pipe
また、最初のパラメータprintf
は型なので、そこに変数があってはいけません。行区切りなしで入力行を印刷するには、次のようにします。
printf %s "$line"