Saya memiliki hard drive yang diisi dengan angka nol.
Bagaimana memeriksa apakah semua bit pada hard drive nol menggunakan bash?
Saya memiliki hard drive yang diisi dengan angka nol.
Bagaimana memeriksa apakah semua bit pada hard drive nol menggunakan bash?
Jawaban:
od
akan menggantikan proses yang sama dengan *
, sehingga Anda dapat dengan mudah menggunakannya untuk memindai byte yang bukan nol:
$ sudo od /dev/disk2 | head
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
234250000
| head
pada akhirnya, sehingga jika ternyata drive tidak memusatkan perhatian, berhenti setelah hanya menghasilkan output yang cukup untuk menunjukkan fakta, alih-alih membuang seluruh drive ke layar.
Saya telah menulis program C ++ singkat untuk melakukannya, sumber tersedia di sini .
Untuk membangunnya:
wget -O iszero.cpp https://gist.github.com/BobVul/5070989/raw/2aba8075f8ccd7eb72a718be040bb6204f70404a/iszero.cpp
g++ -o iszero iszero.cpp
Untuk menjalankannya:
dd if=/dev/sdX 2>/dev/null | ./iszero
Ini akan menampilkan posisi dan nilai byte yang bukan nol. Anda dapat mengarahkan output ini ke file dengan>
, misalnya:
dd if=/dev/sdX 2>/dev/null | ./iszero >nonzerochars.txt
Anda mungkin ingin mencoba mengubah BUFFER_SIZE
untuk efisiensi yang lebih baik. Saya tidak yakin apa nilai optimalnya. Perhatikan bahwa ini juga memengaruhi seberapa sering ia mencetak kemajuan, yang agaknya akan mempengaruhi kecepatan (hasil cetak ke konsol lambat ). Tambahkan 2>/dev/null
untuk menyingkirkan hasil kemajuan.
Saya sadar ini tidak menggunakan standar bash, atau bahkan builtin, tetapi seharusnya tidak memerlukan hak istimewa tambahan. Solusi @Hennes masih lebih cepat (saya belum benar-benar mengoptimalkan apa pun - ini adalah solusi naif); Namun, program kecil ini dapat memberi Anda gambaran yang lebih baik tentang berapa banyak byte yang dihapus oleh wiper Anda, dan di lokasi apa. Jika Anda menonaktifkan output progres, itu masih akan lebih cepat daripada yang dapat dibaca oleh kebanyakan hard drive konsumen (> 150 MB / s), jadi itu bukan masalah besar.
Versi yang lebih cepat dengan output yang lebih sedikit tersedia di sini . Namun, masih sedikit lebih lambat dari solusi @ Henne. Yang ini, bagaimanapun, akan berhenti pada karakter bukan nol pertama yang dihadapinya sehingga berpotensi jauh lebih cepat jika ada nol di dekat awal aliran.
Menambahkan sumber ke pos untuk menjaga agar jawaban tetap lengkap:
#include <cstdio>
#define BUFFER_SIZE 1024
int main() {
FILE* file = stdin;
char buffer[BUFFER_SIZE];
long long bytes_read = 0;
long long progress = 0;
long long nonzero = 0;
while (bytes_read = fread(buffer, 1, BUFFER_SIZE, file)) {
for (long long i = 0; i < bytes_read; i++) {
progress++;
if (buffer[i] != 0) {
nonzero++;
printf("%lld: %x\n", progress, buffer[i]);
}
}
fprintf(stderr, "%lld bytes processed\r", progress);
}
fprintf(stderr, "\n");
int error = 0;
if (error = ferror(file)) {
fprintf(stderr, "Error reading file, code: %d\n", error);
return -1;
}
printf("%lld nonzero characters encountered.\n", nonzero);
return nonzero;
}
iszero /dev/sda
daripada mengharuskannya untuk disalurkan dengan sesuatu seperti iszero < /dev/sda
?
int main(int argc, char *argv[])
lalu FILE* file = fopen(argv[1], "r");
. Dilakukan dengan benar itu termasuk memeriksa apakah argumen itu benar-benar ada, memeriksa kesalahan berhasil terbuka (melakukan pemeriksaan tambahan ferror
setelah fopen
), dll, tetapi terlalu banyak kesulitan untuk program sekali pakai.
gcc
itu tidak selalu tersedia di semua distro Linux tanpa menarik paket tambahan. Kemudian lagi numpy juga bukan bagian dari paket Python standar ...
-O3
dan -march=native
Anda mungkin melihat beberapa speedups; yang seharusnya memastikan GCC mengaktifkan auto-vectorisation dan menggunakan yang terbaik yang tersedia untuk CPU Anda saat ini (AVX, SSE2 / SSE3, dll.). Bersamaan dengan itu Anda bisa bermain dengan ukuran buffer; ukuran buffer yang berbeda mungkin lebih optimal dengan loop vectorised (saya akan bermain dengan 1MB +, yang sekarang adalah 1kB).
@Bob
) dalam obrolan: chat.stackexchange.com/rooms/118/root-access
Memperluas jawaban Gordon, pv
memberikan indikasi seberapa jauh prosesnya adalah:
$ sudo pv -tpreb /dev/sda | od | head
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
9.76GiB 0:06:30 [25.3MiB/s] [=================> ] 59% ETA 0:04:56
Ini sepertinya solusi yang tidak efisien dan jelek, tetapi jika Anda hanya perlu memeriksa sekali:
dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
Menggunakan dd untuk membaca dari disk sdX
. (ganti X dengan drive yang ingin Anda baca),
Kemudian terjemahkan semua byte nol yang tidak dapat diproduksi menjadi sesuatu yang dapat kami tangani.
Selanjutnya kita menghitung byte yang bisa kita tangani dan periksa apakah itu angka yang tepat (gunakan wc -c
untuk itu), atau kita lewati menghitung dan menggunakan -s
atau--squeeze-repeats
untuk memeras semua kemunculan banyak ke satu karakter.
Dengan demikian dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
harus mencetak hanya satu T.
Jika Anda ingin melakukan ini secara teratur maka Anda menginginkan sesuatu yang lebih efisien.
Jika Anda ingin melakukan ini hanya sekali saja maka kludge ini dapat memverifikasi bahwa penghapus normal Anda berfungsi dan Anda dapat mempercayainya.
Untuk memeriksa saja, Anda akan melihat blok apa pun yang tidak cocok tercantum
sudo badblocks -sv -t 0x00 /dev/sdX
Atau gunakan badblock untuk menulisnya serta memeriksa:
sudo badblocks -svw -t 0x00 /dev/sdX
Tes destrucive default adalah penghapusan pilihan saya yang aman
sudo badblocks -svw /dev/sdX
Jika ada yang bisa mengambil apa pun setelah mengisi drive dengan 0s dan 1s bergantian, maka pelengkap mereka, maka semua 1s, lalu semua 0s, dengan setiap pass diverifikasi berfungsi, semoga sukses untuk mereka!
Melakukan pemeriksaan pra-penempatan yang baik pada drive baru juga
man badblocks
untuk opsi lain
Tidak mengatakan itu cepat, tetapi berhasil ...
Terbaik dari kedua dunia. Perintah ini akan melewati bad sector:
sudo dd if=/dev/sdX conv=noerror,sync | od | head
Gunakan kill -USR1 <pid of dd>
untuk melihat kemajuan.
Beberapa waktu lalu saya penasaran AIO
. Hasilnya adalah program uji sampel yang terjadi untuk memeriksa sektor (blok 512 byte) yang NUL
. Anda dapat melihat ini sebagai varian dari detektor wilayah file yang jarang . Saya pikir sumber mengatakan semuanya.
NUL
terlihat seperti output 0000000000-eof
. Perhatikan bahwa ada trik dalam fungsi programfin()
tidak dipanggil pada baris 107 dengan sengaja untuk memberikan hasil yang ditunjukkan.AIO
tidak lurus seperti cara lain,AIO
adalah mungkin cara tercepat untuk menjaga drive sibuk membaca , karena NUL
membandingkan dilakukan sedangkan blok data berikutnya dibaca dalam. (Kita bisa memeras beberapa milidetik lebih dengan melakukan tumpang tindihAIO
, tapi aku benar-benar tidak berpikir ini bernilai upaya.)true
jika file dapat dibaca dan semuanya berfungsi. Itu tidak kembali false
jika file tersebut bukanNUL
.NUL
masih berfungsi, karena buffer memori sudah berisi NUL
. Jika seseorang berpikir ini perlu diperbaiki, pada baris 95 memcmp(nullblock, buf+off, SECTOR)
bisa dibaca memcmp(nullblock, buf+off, len-off<SECTOR : len-off : SECTOR)
. Tetapi satu-satunya perbedaan adalah, bahwa "pelaporan akhir" mungkin agak acak (bukan untuk file yang seluruhnya NUL
).memcmp()
juga memperbaiki masalah lain pada platform, yang tidak mengubah NUL
alloc()
memori, karena kode tidak melakukannya. Tapi ini hanya dapat dilihat oleh file kurang dari 4 MiB, tapi checknul
mungkin berlebihan untuk tugas sekecil itu;)HTH
/* Output offset of NUL sector spans on disk/partition/file
*
* This uses an AIO recipe to speed up reading,
* so "processing" can take place while data is read into the buffers.
*
* usage: ./checknul device_or_file
*
* This Works is placed under the terms of the Copyright Less License,
* see file COPYRIGHT.CLL. USE AT OWN RISK, ABSOLUTELY NO WARRANTY.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <aio.h>
#define SECTOR 512
#define SECTORS 40960
#define BUFFERLEN (SECTOR*SECTORS)
static void
oops(const char *s)
{
perror(s);
exit(1);
}
static void *
my_memalign(size_t len)
{
void *ptr;
static size_t pagesize;
if (!pagesize)
pagesize = sysconf(_SC_PAGESIZE);
if (len%pagesize)
oops("alignment?");
ptr = memalign(pagesize, len);
if (!ptr)
oops("OOM");
return ptr;
}
static struct aiocb aio;
static void
my_aio_read(void *buf)
{
int ret;
aio.aio_buf = buf;
ret = aio_read(&aio);
if (ret<0)
oops("aio_read");
}
static int
my_aio_wait(void)
{
const struct aiocb *cb;
int ret;
cb = &aio;
ret = aio_suspend(&cb, 1, NULL);
if (ret<0)
oops("aio_suspend");
if (aio_error(&aio))
return -1;
return aio_return(&aio);
}
static unsigned long long nul_last;
static int nul_was;
static void
fin(void)
{
if (!nul_was)
return;
printf("%010llx\n", nul_last);
fflush(stdout);
nul_was = 0;
}
static void
checknul(unsigned long long pos, unsigned char *buf, int len)
{
static unsigned char nullblock[SECTOR];
int off;
for (off=0; off<len; off+=SECTOR)
if (memcmp(nullblock, buf+off, SECTOR))
fin();
else
{
if (!nul_was)
{
printf("%010llx-", pos+off);
fflush(stdout);
nul_was = 1;
}
nul_last = pos+off+SECTOR-1;
}
}
int
main(int argc, char **argv)
{
unsigned char *buf[2];
int fd;
int io, got;
buf[0] = my_memalign(BUFFERLEN);
buf[1] = my_memalign(BUFFERLEN);
if (argc!=2)
oops("Usage: checknul file");
if ((fd=open(argv[1], O_RDONLY))<0)
oops(argv[1]);
aio.aio_nbytes = BUFFERLEN;
aio.aio_fildes = fd;
aio.aio_offset = 0;
io = 0;
my_aio_read(buf[io]);
while ((got=my_aio_wait())>0)
{
unsigned long long pos;
pos = aio.aio_offset;
aio.aio_offset += got;
my_aio_read(buf[1-io]);
checknul(pos, buf[io], got);
io = 1-io;
}
if (got<0)
oops("read error");
printf("eof\n");
close(fd);
return 0;
}
Ingin memposting solusi pintar ini dari pertanyaan yang serupa tetapi sebelumnya, diposkan oleh pengguna yang belum masuk untuk sementara waktu:
Ada sebuah perangkat
/dev/zero
di sistem Linux yang selalu memberikan angka nol saat membaca.Jadi, bagaimana dengan membandingkan hard drive Anda dengan perangkat ini:
cmp /dev/sdX /dev/zero
Jika semuanya baik-baik saja dengan memusatkan perhatian pada hard drive Anda, itu akan berakhir dengan:
cmp: EOF on /dev/sdb
memberi tahu Anda bahwa kedua file itu sama hingga mencapai ujung hard drive. Jika ada bit yang tidak nol pada hard drive
cmp
akan memberi tahu Anda di mana file itu berada.Jika Anda memiliki
pv
paket yang diinstal maka:pv /dev/sdX | cmp /dev/zero
akan melakukan hal yang sama dengan progress bar untuk membuat Anda tetap terhibur saat memeriksa drive Anda (EOF sekarang akan berada pada STDIN daripada sdX sekalipun).