名前付きパイプをnetcatのデータソースとして使用する

名前付きパイプをnetcatのデータソースとして使用する

名前付きパイプからデータを読み取る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代わりに を使用すると終了nccatます。

ただし、nc標準出力はこの時点で依然として端末に到着し、TCP接続はまだアクティブであるため、一方の端が入力端に到達しても続行されます。たとえば、bashそのソケットに何かを送信すると、stdoutに表示されます。nc

2番目の操作を実行すると、パイプのfdがまだ閉じていないecho something > /tmp/all.pipeため(少なくともUbuntu、YMMVパッケージの場合)、再びオンラインになるのと同じパイプを通過しましたが、放棄しました。後で読むと、早くeofに達しました。ncncnetcat-openbsdnc

ここで最も簡単なのは、パイプの入力を読み取り+書き込みモードで開いて、即座にncインスタンス化され、nc寿命の間常に維持されるようにすることです。

これを行うには、コマンドラインを<次のように置き換えます。<>nc

nc -k -l 8080 <> /tmp/all.pipe

また、最初のパラメータprintfは型なので、そこに変数があってはいけません。行区切りなしで入力行を印刷するには、次のようにします。

printf %s "$line"

おすすめ記事