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
| headpada 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_SIZEuntuk 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/nulluntuk 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/sdadaripada 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 ferrorsetelah fopen), dll, tetapi terlalu banyak kesulitan untuk program sekali pakai.
gccitu tidak selalu tersedia di semua distro Linux tanpa menarik paket tambahan. Kemudian lagi numpy juga bukan bagian dari paket Python standar ...
-O3dan -march=nativeAnda 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, pvmemberikan 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 -cuntuk itu), atau kita lewati menghitung dan menggunakan -satau--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.
NULterlihat 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,AIOadalah mungkin cara tercepat untuk menjaga drive sibuk membaca , karena NULmembandingkan 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.)truejika file dapat dibaca dan semuanya berfungsi. Itu tidak kembali falsejika file tersebut bukanNUL .NULmasih 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 checknulmungkin 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/zerodi sistem Linux yang selalu memberikan angka nol saat membaca.Jadi, bagaimana dengan membandingkan hard drive Anda dengan perangkat ini:
cmp /dev/sdX /dev/zeroJika semuanya baik-baik saja dengan memusatkan perhatian pada hard drive Anda, itu akan berakhir dengan:
cmp: EOF on /dev/sdbmemberi tahu Anda bahwa kedua file itu sama hingga mencapai ujung hard drive. Jika ada bit yang tidak nol pada hard drive
cmpakan memberi tahu Anda di mana file itu berada.Jika Anda memiliki
pvpaket yang diinstal maka:pv /dev/sdX | cmp /dev/zeroakan 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).