Inilah salah satu cara untuk mendapatkan 1024 byte terakhir dari perangkat blok:
last_bytes() { sudo dd if=$2 iflag=skip_bytes skip=$(($(sudo blockdev --getsize64 $2) - $1)) bs=1M ; } ; last_bytes 1024 DEVICE
Ganti DEVICEdengan jalur perangkat. Dalam kasus Anda, Anda akan menggunakannya /dev/sda2.
Sekarang untuk pertanyaan yang lebih menarik untuk dijawab ...
Mengapa tail -c 1024 /dev/sda2mencari seluruh disk?
Alasannya bagaimana tailpenerapannya. Ketika tailtahu ukuran file yang dibacanya, ia tahu persis berapa banyak yang harus dicari. Kalau tidak, ia harus membaca file atau streaming sepanjang jalan untuk mengetahui seberapa jauh untuk menghitung mundur.
Dengan pipa, masuk akal, seperti cat /dev/sda2 | tail -c 1024. tailmenerima konten sebagai aliran dan tidak memiliki cara untuk mengetahui kapan data akan berakhir.
Anda mungkin berharap tail -c 1024 /dev/sda2dapat mengetahui ukuran /dev/sda2, tetapi sebenarnya, ketika tailmelihat ke atas /dev/sda2, itu dibuka sebagai perangkat blok bukan file biasa.
Detail implementasi adalah tailpanggilan fstat()untuk mendapatkan informasi tentang file.
tail pada file biasa
Inilah bagian yang relevan stracedari contoh tailmembuka file:
21:30:27 open("/var/log/syslog", O_RDONLY) = 3
21:30:27 fstat(3, {st_dev=makedev(0, 22), st_ino=4715, st_mode=S_IFREG|0640, st_nlink=1, st_uid=104, st_gid=4, st_blksize=131072, st_blocks=54, st_size=175500, st_atime=2017/11/10-21:28:39.243133398, st_mtime=2017/11/10-21:30:20.438031639, st_ctime=2017/11/10-21:30:20.438031639}) = 0
21:30:27 lseek(3, 0, SEEK_CUR) = 0
21:30:27 lseek(3, 174476, SEEK_SET) = 174476
fstat()menyediakan st_size=175500. Sekarang tailhanya perlu menghitung mundur 1024 byte:
175500 - 1024 = 174476
... dan inilah tepatnya yang taildilakukannya:
lseek(3, 174476, SEEK_SET) = 174476
tail pada perangkat blok
fstat() tidak mengembalikan ukuran saat ini !:
21:29:43 open("/dev/sda", O_RDONLY) = 3
21:29:43 fstat(3, {st_dev=makedev(0, 6), st_ino=17488, st_mode=S_IFBLK|0660, st_nlink=1, st_uid=0, st_gid=6, st_blksize=4096, st_blocks=0, st_rdev=makedev(8, 0), st_atime=2017/11/10-09:21:15.643998960, st_mtime=2017/11/10-09:21:15.555998962, st_ctime=2017/11/10-09:21:15.555998962}) = 0
Tanpa st_size, tailtidak dapat mengetahui sejauh mana pencarian, sehingga default untuk membaca seluruh perangkat blok hingga akhir.
Inilah sebabnya mengapa Anda umumnya harus menggunakan alat blok perangkat suka ddmemanipulasi perangkat blok daripada alat yang ditujukan untuk file biasa seperti tail.
Anda mungkin bertanya, "Seberapa blockdev --getsize64cepat mendapatkan ukuran perangkat blok?"
Inilah sudo strace -vvvfts1000 blockdev --getsize64 /dev/sda:
21:53:15 open("/dev/sda", O_RDONLY) = 3
21:53:15 ioctl(3, BLKGETSIZE64, [512110190592]) = 0
blockdevdimaksudkan untuk mendapatkan perangkat blok ioctls, dan BLKGETSIZE64mendapatkan ukuran perangkat blok.
Adapun mengapa tail tidak melakukannya BLKGETSIZE64, saya tidak tahu. The kode sumber menunjukkan:
#define IS_TAILABLE_FILE_TYPE(Mode) \
(S_ISREG (Mode) || S_ISFIFO (Mode) || S_ISSOCK (Mode) || S_ISCHR (Mode))
Saya hanya tahu dari baris itu bahwa tanpa S_ISBLK(), penulis tidak bermaksud tailmendukung perangkat blok.