Двоичный хвост файла

Я предполагаю, что большинство людей на этом сайте знакомы с хвостом, если нет - он обеспечивает режим «следования», который, когда текст добавляется к файлу, хвост выводит эти символы на терминал.

Я ищу (и, возможно, при необходимости напишу сам) версию tail, которая работает с бинарными файлами. По сути, у меня есть беспроводная связь, по которой я хотел бы передать файл, когда он поступает из другой сетевой ссылки. Глядя на исходный код хвоста, было бы несложно переписать его, но я бы не стал изобретать велосипед! Это не будет строго «хвост», так как я хотел бы, чтобы весь файл был скопирован, но он будет следить за добавлением новых байтов и передавать их.

Идеи?


person Goyuix    schedule 24.10.2008    source источник


Ответы (8)


Существует также приложение bintail, которое кажется более надежным, чем вышеупомянутый скрипт.

Пакет bintail содержит одно приложение bintail. Программа читает обычный файл с диска и направляет вывод на стандартный вывод, байт за байтом, без перевода, подобно тому, как tail(1) делает с текстовыми файлами. Это полезно для «отслеживания» двоичных файлов, таких как файлы WAV, во время их записи в реальном времени. Это приложение находится в стадии разработки, но оно уже делает то, для чего было разработано для меня.

person Bin Tail    schedule 30.05.2011
comment
Спасибо, это именно то, что мне было нужно, чтобы перенаправить вывод из tcpflow в поток nodejs :) Это не сработало с tail -f. - person Drasill; 08.10.2013
comment
В Linux binutils tail -c +1 -f somefile работает так же хорошо. - person ruief; 25.07.2017

Передайте его в шестнадцатеричный дамп:

tail -f somefile | hexdump -C
person Adam Pierce    schedule 24.10.2008
comment
Я сам не был на 100% уверен, но я попробовал, и это работает просто отлично. - person Adam Pierce; 24.10.2008
comment
Не будет ли tail -f выводить новые данные только тогда, когда он увидит новую строку в двоичном файле? Я сомневаюсь, что он не буферизует свой стандартный вывод. - person Chris Young; 24.10.2008
comment
Хороший вопрос, Крис, я не подумал об этом. Поэтому я только что протестировал его на Debian, и да, он все еще работает, если в потоке нет новых строк, хотя это поведение может отличаться на разных платформах. - person Adam Pierce; 24.10.2008
comment
Использование hexdump — отвлекающий маневр, не так ли? Или, возможно, просто иллюстрация того, куда отправлять двоичные данные. Я не вижу ничего в вопросе о шестнадцатеричном дампе, вот и все... - person Jonathan Leffler; 24.10.2008
comment
Обратите внимание, что hexdump выводит на экран только логи с шагом 16 байт. - person CletusW; 04.07.2020

Linux coreutils tail(1) прекрасно работает с бинарными файлами. Для большинства приложений вам просто нужно избегать его линейной ориентации, чтобы вывод не начинался в каком-то случайном месте в середине структуры данных. Вы можете сделать это, просто начав с начала файла, что также является именно тем, о чем вы просили:

tail -c +1 -f somefile

работает просто отлично.

person ruief    schedule 25.07.2017

Этот наспех написанный скрипт Python для Windows может помочь:

# bintail.py -- reads a binary file, writes initial contents to stdout,
# and writes new data to stdout as it is appended to the file.

import time
import sys
import os
import msvcrt
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

# Time to sleep between file polling (seconds)
sleep_int = 1

def main():
    # File is the first argument given to the script (bintail.py file)
    binfile = sys.argv[1]

    # Get the initial size of file
    fsize = os.stat(binfile).st_size

    # Read entire binary file
    h_file = open(binfile, 'rb')
    h_bytes = h_file.read(128)
    while h_bytes:
        sys.stdout.write(h_bytes)
        h_bytes = h_file.read(128)
    h_file.close()


    # Loop forever, checking for new content and writing new content to stdout
    while 1:
        current_fsize = os.stat(binfile).st_size
        if current_fsize > fsize:
            h_file = open(binfile, 'rb')
            h_file.seek(fsize)
            h_bytes = h_file.read(128)
            while h_bytes:
                sys.stdout.write(h_bytes)
                h_bytes = h_file.read(128)
            h_file.close()
            fsize = current_fsize
        time.sleep(sleep_int)

if __name__ == '__main__':
    if len(sys.argv) == 2:
        main()
    else:
        sys.stdout.write("No file specified.")
person Bin Tail    schedule 30.05.2011

less somefile

Затем нажмите shift F

person mhawke    schedule 24.10.2008
comment
Я не понимаю, как я мог бы использовать less, чтобы перенаправить на вывод файла и нажать Shift + F... - person Goyuix; 05.10.2010

Строго говоря, вам нужно написать программу для этого, так как tail не предназначен для работы с двоичными файлами. Есть также проблемы с буферизацией, которых вы, вероятно, захотите избежать, если хотите получать новые «просачивающиеся» данные как можно скорее.

person R.. GitHub STOP HELPING ICE    schedule 04.10.2010
comment
Что ж, посмотрев еще раз, я увидел, что вы отметили свой вопрос тегом gnu-coreutils. Так что, если вы знаете, что будете использовать реализацию tail в gnu, вероятно, она безопасна для двоичных файлов и, возможно, не имеет проблемной буферизации (проверьте и посмотрите). - person R.. GitHub STOP HELPING ICE; 04.10.2010

Это не хвост — это последовательное копирование файла. Посмотри рсинк.

person wnoise    schedule 24.10.2008
comment
Интересно, что этот ответ является принятым, где есть два ответа, которые гораздо больше соответствуют вопросу: stackoverflow.com/a/6171491/1353930. rsync здесь бесполезен, потому что он не может передавать данные. он ограничен (относительно статическими) файлами на диске - person Daniel Alder; 16.11.2015
comment
@ Дэниэл Алдер. rsync можно перезапустить, отправляя только новые данные. - person wnoise; 16.11.2015
comment
потоковая передача означает, что вы находитесь внутри сценария cgi, запускаемого или подключаемого к netcat и т. д. Но это был больше вопрос в @Goyuix - person Daniel Alder; 16.11.2015

Я использую это, так как оно работает и в прямых трансляциях:

cat ./some_file_or_dev | hexdump -C

пример сброса моих нажатий клавиш (и отпусканий):

[user@localhost input]$ sudo cat /dev/input/event2 | hexdump -C
00000000  81 32 b1 5a 00 00 00 00  e2 13 02 00 00 00 00 00  |.2.Z............|
00000010  04 00 04 00 36 00 00 00  81 32 b1 5a 00 00 00 00  |....6....2.Z....|
00000020  e2 13 02 00 00 00 00 00  01 00 36 00 01 00 00 00  |..........6.....|
00000030  81 32 b1 5a 00 00 00 00  e2 13 02 00 00 00 00 00  |.2.Z............|
00000040  00 00 00 00 00 00 00 00  81 32 b1 5a 00 00 00 00  |.........2.Z....|
00000050  a3 af 02 00 00 00 00 00  04 00 04 00 36 00 00 00  |............6...|
00000060  81 32 b1 5a 00 00 00 00  a3 af 02 00 00 00 00 00  |.2.Z............|
^C
person Anonymous    schedule 20.03.2018
comment
Проблема с hexdump заключается в том, что он ожидает кратных 16 байтов для печати каждой строки, но пока вы знаете об этой проблеме, все в порядке. - person José Tomás Tocino; 08.01.2019
comment
Вероятно, это из-за ключа -C (столбец ascii) - person Anonymous; 09.01.2019