2010-04-28 1 views
1

Я хочу запустить хвост по именованному каналу, чтобы облегчить обработку двоичного журнала. Проблема в том, что таинственные данные добавляются в начало потока. Я запускаю свои тесты, запустив процесс erlang с открытым портом (open_port), а затем я использую другую оболочку для посылки bin в именованный канал.Хвост двоичного файла в Erlang добавляет таинственную битовую строку

Вот простая функция для получения данных из порта:

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

Так вот два пути для меня, чтобы захватить одни и те же данные ...

  1. Создать именованный канал

    mkfifo named_pipe

  2. Эта команда блокируется до тех пор, пока вы не запустите «c на log.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>> 

ответ

1

я нашел то же самое произошло за пределами Erlang. Проблема в том, что tail пытается показать вам конец файла, а не весь файл. Если вы используете его в обычном файле, все написанное будет новым и будет получено -f, но в этом случае оно выглядит так: хвост ждет до конца файла (eof, который поступает через трубу), а затем показаны последние 10 строк (обработка двоичного файла как текста).

tail -F -c 9999999 

(при условии, что ваш журнал равен 9999999 байт или меньше), вероятно, будет работать.

Может попробовать использовать кошку вместо хвост -F, который, казалось, работать для меня. Тогда вам просто нужно избегать того, что cat выходит на eof, который, как я полагаю, вы пытались избежать, используя хвост.

Итак, сценарий оболочки, который петли cat бесконечно, может быть?

Или получите erlang, чтобы перезапустить закрытие и воссоздать порт, когда он умирает, так как вы все равно получаете сигнал eof. Или используйте флаг exit_status для open_port, который будет сигнализироваться при выходе из процесса, если вам нужно будет отличить eof и выйти из процесса. (Если вы используете оба статус_выхода и EOF, то ВФ никогда не приходит, краткий тест с кошки </Dev/нуль указывает)

2

Спасибо за идею о бесконечно обхвата кошки/повторный запуск мертвого порта. Похоже, что именованные каналы buffer немного, поэтому, если порт открывается достаточно быстро, процесс записи (другая программа) не будет разбиваться!Определенно рискованные вещи, но насколько хаки идут ... это работает.

Потому что все сообщения только для рассылки делают это, сделайте это без примеров, я опубликую, как работает мой! Если кто-то хочет предложить улучшения, пожалуйста, не стесняйтесь. Мое решение:

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). 
+0

Bigup! Спасибо, что поделился. Как вы сказали, все говорят об этом, и никто не делится примером кода. –