名前付きパイプへの連続書き込み

名前付きパイプへの連続書き込み

解決できない2つの名前付きパイプに関する問題があります。基本的に私が制御できない2つのプロセスがあります。名前付きパイプ()を介して通信しますmknod pipe p。プロセス1は、NMEA0183形式でメッセージを出力するGPSドライバである。プロセス2は、NMEA0183データを読み取り、GPSから位置と日付/時刻を取得するナビゲーションアプリケーションです。このデータを調整する必要があります(理由:GoogleがWNROを検索または連絡する)。

  1. 最初のプロセスは、1秒間隔で/var/run/one.pipeに継続的にデータ(〜5〜8行のテキスト)を書き込み、読み取るまで(?)まで残します。

  2. 2番目のプロセスは、名前付きパイプからこのデータを読み取ることです。読み取る名前付きパイプの名前を変更できます。 /var/run/two.pipeに変更しました。

最後の目標は、one.pipeからデータを読み取り、いくつかの処理を実行してからTwo.pipeに渡すことです。しかし、これまでテスト目的でone.pipeからTwo.pipeにデータを一つずつコピーしてみました。この(より簡単ですか?)作業を完了できるまで、このプロセス全体で時間を無駄にすることは不可能だと思います。

非常に単純なシェルスクリプトが動作します:copy.sh

#!/bin/sh
cat one.pipe > two.pipe &

これで、ソースプロセスで作成されたいくつかのデータをキャプチャし、読み取りプロセスが読み取れるようにone.pipe手動で作成しようとしています。two.pipe

#!/bin/sh

while true; do
  echo "\$GPGGA,,,,,,,,*12" > two.pipe
  echo "\$GPGSA,,,,,,,,*23" > two.pipe
  echo "\$GPRMC,,,,,,,,*34" > two.pipe
  echo "\$GPGSV,,,,,,,,*45" > two.pipe
  echo "\$GPGSV,,,,,,,,*56" > two.pipe
  echo "\$GPGSV,,,,,,,,*67" > two.pipe
  # checksums (*xx) are just examples here
  sleep 1 > two.pipe
done

今これはうまくいきません。cat one.pipeと比較すると、 のメッセージが「積み重ね」ではなく、作成された元のプロセスでたまっていることがcat two.pipeわかります。たとえば、スクリプトを起動したら、名前付きパイプに書き込んで作成し続ける必要があります。パイプを読み取るために使用すると、これまでのすべてのデータが出力されます(fifoバッファがまだ満たされていないと仮定)。結局は最初に入ったのがまずなのではないでしょうか?two.pipeone.pipecat

さらに、今では猫は見かけ上ランダムに停止することがよくあります。最後に、two.pipeデータが正しく処理されない、またはスクリプトが終了するプロセスを読み取るプロセスを制御できません。

無限ループが含まれていても、スクリプトが終了する理由を理解していませんか? !

ここで何を監視していますか?シェルで作成することができない場合は、Cもオプションです。

答え1

while true; do
  echo "\$GPGGA,,,,,,,,*12" > two.pipe
  echo "\$GPGSA,,,,,,,,*23" > two.pipe
  ...

... > two.pipeスクリプトの各行が開き、閉鎖fifoをtwo.pipe閉じると、パイプのもう一方の端で読み取りがファイルの終わりを返してcat終了する可能性があります。

FIFOを最初から開くことをお勧めします一度フルスクリプトの場合exec

#!/bin/sh

exec > two.pipe

while true; do
  echo "\$GPGGA,,,,,,,,*12"
  echo "\$GPGSA,,,,,,,,*23"
  ...
  sleep 1
done

たとえば、fifo の両端を同じハンドルで開き、fifo を「固定」できます。

exec 7<>two.fifo

これを実行するプロセスが終了せず、ファイル記述子が閉じられない限り、他のすべてのハンドルがそのファイル記述子を7処理している間に、そのファイル記述子から読み取られるプロセスがファイルの終わりを取得できないことが保証されます。書くSIGPIPEendが閉じてここに書き込むプロセスは、他のすべてのハンドルがそれを指している間は終了しません。読む先端が閉じています。

また、指定されたfifoの両端を同時に開いてもブロックされません。

関連情報