Вот один из способов получить последние 1024 байта блочного устройства:
last_bytes() { sudo dd if=$2 iflag=skip_bytes skip=$(($(sudo blockdev --getsize64 $2) - $1)) bs=1M ; } ; last_bytes 1024 DEVICE
Замените DEVICE
путь устройства. В вашем случае вы бы использовали /dev/sda2
.
Теперь на более интересный вопрос, чтобы ответить ...
Почему tail -c 1024 /dev/sda2
поиск по всему диску?
Причина в том, как tail
это реализовано. Когда tail
знает размер файла, который он читает, он точно знает, сколько искать. В противном случае, он должен прочитать файл или поток полностью, чтобы выяснить, как далеко отсчитывать.
С трубами это имеет смысл, вроде cat /dev/sda2 | tail -c 1024
. tail
получает содержимое в виде потока и не может знать, когда данные закончатся.
Вы можете ожидать, tail -c 1024 /dev/sda2
что сможете определить размер /dev/sda2
, но на самом деле, когда вы tail
смотрите вверх /dev/sda2
, он открывается как блочное устройство вместо обычного файла.
Детали реализации - это tail
вызовы fstat()
для получения информации о файле.
tail
на обычном файле
Вот соответствующая часть strace
примера tail
открытия файла:
21:30:27 open("/var/log/syslog", O_RDONLY) = 3 21:30:27 fstat(3, ) = 0 21:30:27 lseek(3, 0, SEEK_CUR) = 0 21:30:27 lseek(3, 174476, SEEK_SET) = 174476
fstat()
обеспечивает st_size=175500
. Теперь tail
просто нужно отсчитать 1024 байта:
175500 - 1024 = 174476
... и это именно то, что
tail
делает:lseek(3, 174476, SEEK_SET) = 174476
tail
на блочном устройстве
fstat()
не возвращает размер на этот раз!
21:29:43 open("/dev/sda", O_RDONLY) = 3 21:29:43 fstat(3, ) = 0
С нет st_size
, tail
не может знать, как далеко искать, поэтому по умолчанию он читает через все блочное устройство до конца.
Вот почему вы должны обычно использовать инструменты блочных устройств, например, dd
для управления блочными устройствами, а не инструменты, предназначенные для обычных файлов, таких как tail
.
Вы можете спросить: «Как blockdev --getsize64
быстро получить размер блочного устройства?»
Вот sudo strace -vvvfts1000 blockdev --getsize64 /dev/sda
:
21:53:15 open("/dev/sda", O_RDONLY) = 3 21:53:15 ioctl(3, BLKGETSIZE64, [512110190592]) = 0
blockdev
предназначен для получения ioctls блочного устройства и BLKGETSIZE64
получения размера блочного устройства.
Что касается почему tail
не делает BLKGETSIZE64
, я не знаю. Исходный код показывает:
#define IS_TAILABLE_FILE_TYPE(Mode) \ (S_ISREG (Mode) || S_ISFIFO (Mode) || S_ISSOCK (Mode) || S_ISCHR (Mode))
Из этой строки я знаю только то, что без них S_ISBLK()
авторы не имели в виду tail
поддержку блочных устройств.