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 DEVICE
dengan jalur perangkat. Dalam kasus Anda, Anda akan menggunakannya /dev/sda2
.
Sekarang untuk pertanyaan yang lebih menarik untuk dijawab ...
Mengapa tail -c 1024 /dev/sda2
mencari seluruh disk?
Alasannya bagaimana tail
penerapannya. Ketika tail
tahu 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
. tail
menerima konten sebagai aliran dan tidak memiliki cara untuk mengetahui kapan data akan berakhir.
Anda mungkin berharap tail -c 1024 /dev/sda2
dapat mengetahui ukuran /dev/sda2
, tetapi sebenarnya, ketika tail
melihat ke atas /dev/sda2
, itu dibuka sebagai perangkat blok bukan file biasa.
Detail implementasi adalah tail
panggilan fstat()
untuk mendapatkan informasi tentang file.
tail
pada file biasa
Inilah bagian yang relevan strace
dari contoh tail
membuka 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 tail
hanya perlu menghitung mundur 1024 byte:
175500 - 1024 = 174476
... dan inilah tepatnya yang tail
dilakukannya:
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
, tail
tidak 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 dd
memanipulasi perangkat blok daripada alat yang ditujukan untuk file biasa seperti tail
.
Anda mungkin bertanya, "Seberapa blockdev --getsize64
cepat 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
blockdev
dimaksudkan untuk mendapatkan perangkat blok ioctls, dan BLKGETSIZE64
mendapatkan 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 tail
mendukung perangkat blok.
iflag=skip_bytes
opsi. Ini memungkinkan seseorang untuk secara efisien melewati bagian input sembarang sembarang independen dari ukuran blok yang digunakan untuk I / O. Orang sering ingin menggunakan besarbs
untuk efisiensi.dd iflag=skip_bytes
sebagai gantinya.