19

次のシナリオを検討してください。

名前の付いたFIFOtestが作成されます。あるターミナルウィンドウ(A)で実行cat <testし、別のターミナルウィンドウ(B)で実行しcat >testます。これで、ウィンドウBに書き込み、ウィンドウAで出力を取得できるようになりました。プロセスAを終了して再起動しても、このセットアップを疑わしいものとして使用することもできます。ただし、ウィンドウBでプロセスを終了すると、Bは(私が知る限り)FIFOを介してEOFをプロセスAに送信し、それも終了します。

実際、EOFで終了しないプロセスを実行した場合でも、プロセスにリダイレクトしたFIFOを使用することはできません。これは、このFIFOが閉じていると見なされるためだと思います。

この問題を回避する方法はありますか?

この問題が発生した理由は、スクリーンセッションで実行されているMinecraftサーバーにコマンドを送信したいためです。例:echo "command" >FIFO_to_server。これはおそらくスクリーンを単独で使用することで可能ですが、私はスクリーンにあまり慣れていません。パイプのみを使用する解決策は、より単純でクリーンなものになると思います。

4

4 に答える 4

32

Aはファイルから読み取っています。ファイルの終わりに達すると、読み取りを停止します。ファイルがたまたまFIFOであったとしても、これは正常な動作です。これで、4つのアプローチがあります。

  1. リーダーのコードを変更して、ファイルの終了後も読み続けるようにします。つまり、入力ファイルは無限であり、ファイルの最後に到達するのは単なる幻想です。minecraftサーバーのコードを変更する必要があるため、実用的ではありません。
  2. UNIX哲学を適用します。プロトコルに同意しないライターとリーダーがいるので、それらを接続するツールを挿入します。たまたま、unixツールボックスには次のようなツールがありますtail -ftail -fファイルの終わりを確認した後も、入力ファイルから読み取りを続けます。すべてのクライアントにパイプと通信させtail -f、Minecraftサーバーに接続します。

    tail -n +1 -f client_pipe | minecraft_server &
    
  3. jillesが述べたように、トリックを使用します。パイプは複数のライターをサポートし、最後のライターがいなくなったときにのみ閉じられます。ですから、決して消えることのないクライアントが存在することを確認してください。

    while true; do sleep 999999999; done >client_pipe &
    
  4. 問題は、サーバーが基本的に単一のクライアントを処理するように設計されていることです。複数のクライアントを処理するには、ソケットの使用に変更する必要があります。ソケットを「メタパイプ」と考えてください。ソケットに接続するとパイプが作成され、クライアントが切断されると、その特定のパイプは閉じられますが、サーバーはさらに多くの接続を受け入れることができます。これはクリーンなアプローチです。これは、2つのクライアントが同時に接続した場合にデータが混同されないようにするためです(パイプを使用すると、コマンドが散在する可能性があります)。ただし、Minecraftサーバーを変更する必要があります。

于 2011-05-10T23:08:15.080 に答える
8

FIFOを書き込み用に開いたままにし、無期限に実行し続けるプロセスを開始します。これにより、リーダーにファイルの終わりの状態が表示されなくなります。

于 2011-05-10T22:57:02.910 に答える
1

この答えから-

Linuxなどの一部のシステムでは、名前付きパイプ(FIFO)の<>は、ブロックせずに(他のプロセスがもう一方の端を開くのを待たずに)名前付きパイプを開き、パイプ構造が存続することを保証します。たとえば:

だからあなたはすることができます:

cat <>up_stream >down_stream
# the `cat pipeline keeps running
echo 1 > up_stream  
echo 2 > up_stream
echo 3 > up_stream

ただし、この動作に関するドキュメントが見つかりません。したがって、これは一部のシステムに固有の実装の詳細である可能性があります。MacOSで上記を試しましたが、動作します。

于 2020-08-15T17:35:22.987 に答える
0

'mkfifo yourpipe'にセミコロン付きの角かっこで囲んで必要なものを追加することにより、パイプに複数の入力を追加できます。

(cat file1; cat file2; ls -l;) > yourpipe
于 2018-10-25T09:59:41.673 に答える