1

バイナリログファイルの処理を容易にするために、名前付きパイプでテールを実行したいと思います。問題は、不思議なデータがストリームの先頭に追加されていることです。開いたポート(open_port)でerlangプロセスを開始してテストを実行し、次に別のシェルを使用してビンを名前付きパイプにキャットします。

ポートからデータを取得するための簡単な関数は次のとおりです。

bin_from_tail() ->
  open_port({spawn,"/usr/bin/tail -F named_pipe"},
                             [binary,in,eof]),
  receive
  {_,{data,<<Data/binary>>}} -> Data
  end.

だからここに私が同じデータを取得するための2つの方法があります...

  1. 名前付きパイプを作成します

    mkfifo名前付きパイプ

  2. このコマンドは、別のシェルから「catlog.bin>named_pipe」を実行するまでブロックされます

    {ok、TailBin} = file:read_file(log.bin)。

  3. erlangファイルライブラリFileBin=file:read_file(log.in)を使用して、ファイル全体をメモリに読み込みます。

しかし、TailBinとFileBinは同じではありません!TailBinには、最初に不思議な120バイトの文字列があります。

<<40,6,161,69,172,216,56,14,100,0,80,6,0,0,0>>
4

2 に答える 2

2

猫を際限なくループさせたり、死んだポートを再開したりすることについてのアイデアをありがとう。名前付きパイプはほんの少しバッファリングしているように見えるので、ポートが十分に速く開いていれば、ライタープロセス(別のプログラム)はクラッシュしません!確かに危険なものですが、ハックに関しては...それは機能します。

すべてのメーリングリストの投稿がこれを行うと言っているので、例なしでそれを行います。私がどのように機能するかを投稿します!誰かが改善を提供したいなら、そうしてください。私の解決策:

read() ->
  Port = open_port({spawn,"/bin/cat /path/to/pipe"},
                   [binary,in,eof]),
  do_read(Port).

do_read(Port) ->
  receive
    {Port,{data,<<Data/binary>>}} ->
      case do_something:with(Data) of
        ok ->
          io:format("G") % Good
        Any ->
          io:format("B") % Bad
      end;
    {Port,eof} ->
      read();
    Any ->
      io:format("No match fifo_client:do_read/1, ~p~n",[Any])
  end,
  do_read(Port).
于 2010-05-05T16:40:37.097 に答える
1

同じことがerlangの外で起こっていることがわかりました。問題は、tailがファイル全体ではなく、ファイルの最後を表示しようとしていることです。通常のファイルで使用すると、書き込まれたものはすべて新しくなり、-fによって取得されますが、この場合、ファイルの終わり (パイプを通過するeof ) まで待機してから表示されているように見えます最後の 10 行 (バイナリをテキストとして扱います)。

tail -F -c 9999999

(ログが 9999999 バイト以下であると仮定すると) おそらくうまくいくでしょう。

たぶん、catの代わりにtail -Fを使用してみてください。次に、 catが eof で終了するという事実を回避する必要があります。これは、tail を使用して回避しようとしていたと思われます。

catをエンドレスにループするシェルスクリプトでしょうか?

または、とにかく eof シグナルを取得しているため、erlang を閉じて再起動し、ポートが停止したときにポートを再作成します。または、eof とプロセスの終了を区別する必要がある場合に備えて、open_port に exit_status フラグを使用して、プロセスが終了したときに通知されるようにします。(exit_status と eof の両方を使用する場合、eof は決して来ません。cat < /dev/nullを使用した簡単なテストで示されます)

于 2010-04-29T12:10:39.030 に答える