ฉันมีฮาร์ดไดรฟ์ที่เต็มไปด้วยเลขศูนย์
วิธีตรวจสอบว่าบิตทั้งหมดในฮาร์ดไดรฟ์เป็นศูนย์โดยใช้ bash หรือไม่
ฉันมีฮาร์ดไดรฟ์ที่เต็มไปด้วยเลขศูนย์
วิธีตรวจสอบว่าบิตทั้งหมดในฮาร์ดไดรฟ์เป็นศูนย์โดยใช้ bash หรือไม่
คำตอบ:
od
จะแทนที่การรันในสิ่งเดียวกันด้วย*
ดังนั้นคุณสามารถใช้มันเพื่อสแกนหาไบต์ที่ไม่ใช่ศูนย์:
$ sudo od /dev/disk2 | head
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
234250000
| head
ในตอนท้ายของมันเพื่อที่ว่าถ้ามันเป็นว่าไดรฟ์ไม่ได้เป็นศูนย์ก็จะหยุดหลังจากที่ผลิตเพียงพอที่จะแสดงความจริงแทนการทิ้งไดรฟ์ทั้งหมดไปที่หน้าจอ
ผมเคยเขียนโปรแกรม C ++ สั้นจะทำเช่นนั้นมาใช้ได้ที่นี่
วิธีสร้าง:
wget -O iszero.cpp https://gist.github.com/BobVul/5070989/raw/2aba8075f8ccd7eb72a718be040bb6204f70404a/iszero.cpp
g++ -o iszero iszero.cpp
วิธีเรียกใช้:
dd if=/dev/sdX 2>/dev/null | ./iszero
มันจะส่งออกตำแหน่งและความคุ้มค่าของไบต์ที่ไม่ใช่ศูนย์ใด ๆ คุณสามารถเปลี่ยนเส้นทางผลลัพธ์นี้ไปยังไฟล์ด้วย>
เช่น:
dd if=/dev/sdX 2>/dev/null | ./iszero >nonzerochars.txt
คุณอาจต้องการลองเปลี่ยนBUFFER_SIZE
เพื่อประสิทธิภาพที่ดีขึ้น ฉันไม่แน่ใจว่ามูลค่าที่เหมาะสมอาจเป็นอย่างไร โปรดทราบว่าสิ่งนี้จะส่งผลต่อความถี่ในการพิมพ์ความคืบหน้าซึ่งจะส่งผลต่อความเร็วค่อนข้างมาก (การพิมพ์ไปยังคอนโซลช้า ) เพิ่ม2>/dev/null
เพื่อกำจัดเอาต์พุตความคืบหน้า
ฉันรู้ว่านี่ไม่ได้ใช้ทุบตีมาตรฐานหรือแม้แต่บิวอิน แต่ไม่ควรต้องการสิทธิ์พิเศษใด ๆ @Hennes 'solution ยังเร็วขึ้น (ฉันไม่ได้ปรับอะไรให้ดีที่สุด - นี่เป็นโซลูชั่นที่ไร้เดียงสา); อย่างไรก็ตามโปรแกรมเล็ก ๆ นี้สามารถช่วยให้คุณมีความคิดที่ดีขึ้นว่ามีกี่ไบต์ที่ปัดน้ำฝนที่คุณพลาดและอยู่ในตำแหน่งใด หากคุณปิดใช้งานเอาต์พุตความคืบหน้าจะยังคงเร็วกว่าฮาร์ดไดรฟ์สำหรับผู้บริโภคส่วนใหญ่ที่สามารถอ่านได้ (> 150 MB / s) ดังนั้นจึงไม่ใช่ปัญหาใหญ่
รุ่นที่เร็วขึ้นด้วยน้อย verbose ส่งออกสามารถใช้ได้ที่นี่ อย่างไรก็ตามมันยังช้ากว่าโซลูชันของ @Hennes เล็กน้อย อย่างไรก็ตามตัวนี้จะออกจากตัวละครที่ไม่ใช่ศูนย์แรกที่พบดังนั้นมันอาจจะเร็วกว่ามากถ้ามีค่าที่ไม่ใช่ศูนย์ใกล้จุดเริ่มต้นของกระแส
การเพิ่มแหล่งข้อมูลลงในโพสต์เพื่อให้ตอบเองได้ดีขึ้น
#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
แทนที่จะต้องไปให้ได้รับการประปากับสิ่งที่ต้องการiszero < /dev/sda
?
int main(int argc, char *argv[])
FILE* file = fopen(argv[1], "r");
ทำอย่างถูกต้องซึ่งรวมถึงการตรวจสอบว่ามีข้อโต้แย้งเกิดขึ้นจริงหรือไม่การตรวจสอบข้อผิดพลาดเปิดสำเร็จ (ทำการferror
ตรวจสอบเพิ่มเติมหลังจากfopen
) และอื่น ๆ แต่มีปัญหามากเกินไปสำหรับโปรแกรมการทิ้ง
gcc
ไม่จำเป็นต้องมีใน Linux distros ทั้งหมดโดยไม่ต้องดึงแพ็คเกจเพิ่มเติม จากนั้น numpy อีกครั้งไม่ได้เป็นส่วนหนึ่งของแพคเกจหลามมาตรฐานทั้ง ...
-O3
และ-march=native
คุณอาจเห็น speedups; ที่ควรตรวจสอบให้แน่ใจว่า GCC เปิดใช้งาน auto-vectorisation และใช้งานได้ดีที่สุดสำหรับ CPU ปัจจุบันของคุณ (AVX, SSE2 / SSE3 ฯลฯ ) พร้อมกับที่คุณสามารถเล่นกับขนาดบัฟเฟอร์; ขนาดบัฟเฟอร์ที่แตกต่างกันอาจดีที่สุดเมื่อใช้ vectorised ลูป (ฉันเล่นด้วย 1MB + ปัจจุบันคือ 1kB)
@Bob
) ในการแชท: chat.stackexchange.com/rooms/118/root-access
ขยายคำตอบของกอร์ดอนpv
ให้การบ่งชี้ว่ากระบวนการนั้นไกลแค่ไหน:
$ 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
ดูเหมือนว่าจะเป็นวิธีที่ไม่มีประสิทธิภาพน่าเกลียด แต่ถ้าคุณต้องตรวจสอบเพียงครั้งเดียว:
dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
ใช้ DD sdX
อ่านจากดิสก์ (แทนที่ X ด้วยไดรฟ์ที่คุณต้องการอ่าน)
จากนั้นแปลไบต์ศูนย์ที่ไม่สามารถพิมพ์ได้ทั้งหมดเป็นสิ่งที่เราสามารถจัดการได้
ต่อไปเราจะนับจำนวนไบต์ที่เราสามารถจัดการและตรวจสอบว่าเป็นจำนวนที่ถูกต้อง (ใช้wc -c
สำหรับการนั้น) หรือเราข้ามการนับและใช้-s
หรือ--squeeze-repeats
เพื่อบีบให้เกิดขึ้นหลายเหตุการณ์ทั้งหมดเพื่อถ่านเดียว
ดังนั้นdd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
ควรพิมพ์เพียงทีเดียว
หากคุณต้องการทำสิ่งนี้เป็นประจำคุณต้องการบางสิ่งที่มีประสิทธิภาพมากขึ้น
หากคุณต้องการทำสิ่งนี้เพียงครั้งเดียวกระบองนี้อาจตรวจสอบว่าที่ปัดน้ำฝนปกติของคุณทำงานได้และคุณสามารถเชื่อถือได้
ในการตรวจสอบเท่านั้นคุณจะเห็นบล็อคที่ไม่ตรงกับรายการ
sudo badblocks -sv -t 0x00 /dev/sdX
หรือใช้ badblocks เพื่อเขียนและตรวจสอบ:
sudo badblocks -svw -t 0x00 /dev/sdX
การทดสอบการทำลายล้างเริ่มต้นคือการลบตัวเลือกที่ปลอดภัยของฉัน
sudo badblocks -svw /dev/sdX
หากใครสามารถเรียกคืนข้อมูลใด ๆ หลังจากเติมไดรฟ์ด้วย 0s และ 1s จากนั้นส่วนประกอบของพวกเขาจากนั้น 1s ทั้งหมดจากนั้น 0s ทั้งหมดโดยผ่านการตรวจสอบผ่านทุกครั้งมันทำงานได้ดีโชคดีกับพวกเขา!
ทำการตรวจสอบ pre-deployment ที่ดีสำหรับไดรฟ์ใหม่ด้วย
man badblocks
สำหรับตัวเลือกอื่น ๆ
ไม่ได้บอกว่ามันเร็ว แต่มันใช้งานได้ ...
สุดยอดของทั้งสองโลก คำสั่งนี้จะข้ามเซกเตอร์เสีย:
sudo dd if=/dev/sdX conv=noerror,sync | od | head
ใช้kill -USR1 <pid of dd>
เพื่อดูความคืบหน้า
AIO
บางเวลาที่ผ่านมาผมอยากรู้เกี่ยวกับ ผลที่ได้เป็นโปรแกรมการทดสอบตัวอย่างที่เกิดขึ้นในการตรวจสอบภาค (512 บล็อกไบต์) NUL
ซึ่งเป็น คุณสามารถเห็นนี้เป็นตัวแปรที่เบาบางตรวจจับไฟล์ภูมิภาค ฉันคิดว่าแหล่งที่มาบอกว่ามันทั้งหมด
NUL
0000000000-eof
โปรดทราบว่ามีเคล็ดลับในโปรแกรมฟังก์ชั่นfin()
จะไม่ถูกเรียกที่บรรทัด 107 โดยมีวัตถุประสงค์เพื่อให้ผลลัพธ์ที่แสดงAIO
ไม่ใช่วิธีอื่น ๆ ตรงไปตรงมาAIO
เป็นน่าจะเป็นวิธีที่เร็วที่สุดเพื่อให้ไดรฟ์อ่านไม่ว่างเพราะNUL
เปรียบเทียบจะทำในขณะที่บล็อกข้อมูลต่อไปคือการอ่าน. (เราสามารถบีบออกมิลลิวินาทีอีกไม่กี่ด้วยการทำที่ทับซ้อนกันAIO
แต่ผมไม่คิดว่านี่เป็นมูลค่า ความพยายาม.)true
หากไฟล์นั้นสามารถอ่านได้และทุกอย่างทำงานได้ มันไม่กลับถ้าไฟล์คือไม่ใช่false
NUL
NUL
NUL
หากใครบางคนคิดว่าสิ่งนี้จำเป็นต้องมีการแก้ไขในบรรทัด 95 memcmp(nullblock, buf+off, SECTOR)
สามารถอ่านmemcmp(nullblock, buf+off, len-off<SECTOR : len-off : SECTOR)
ได้ แต่ความแตกต่างเพียงอย่างเดียวคือ "การรายงานสิ้นสุด" อาจเป็นแบบสุ่มเล็กน้อย (ไม่ใช่ไฟล์ที่มีทั้งหมดNUL
)memcmp()
ยังแก้ไขปัญหาอื่นบนแพลตฟอร์มซึ่งไม่ได้ใช้NUL
alloc()
หน่วยความจำเนื่องจากรหัสไม่ได้ทำ แต่ไฟล์นี้อาจเห็นได้น้อยกว่า 4 MiB แต่checknul
อาจเป็น overkill ธรรมดาสำหรับงานเล็ก ๆ น้อย ๆ ;)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;
}
ต้องการโพสต์คำตอบที่ฉลาดนี้จากคำถามที่คล้ายกัน แต่ก่อนหน้านี้โพสต์โดยผู้ใช้ที่ไม่ได้เข้าสู่ระบบในขณะที่:
มีอุปกรณ์
/dev/zero
บนระบบ Linux ที่ให้ค่าเป็นศูนย์เสมอเมื่ออ่านดังนั้นวิธีเปรียบเทียบฮาร์ดไดรฟ์ของคุณกับอุปกรณ์นี้:
cmp /dev/sdX /dev/zero
หากทุกอย่างดีโดยไม่ทำให้ฮาร์ดไดรฟ์ของคุณเป็นศูนย์มันจะจบลงด้วย:
cmp: EOF on /dev/sdb
บอกคุณว่าทั้งสองไฟล์เหมือนกันจนกว่าจะถึงจุดสิ้นสุดของฮาร์ดไดรฟ์ หากมีบิตที่ไม่เป็นศูนย์ในฮาร์ดไดรฟ์
cmp
จะบอกคุณว่ามันอยู่ที่ไหนในไฟล์หากคุณ
pv
ติดตั้งแพ็คเกจแล้ว:pv /dev/sdX | cmp /dev/zero
จะทำสิ่งเดียวกันกับแถบความคืบหน้าเพื่อให้คุณสนุกสนานในขณะที่ตรวจสอบไดรฟ์ของคุณ (EOF จะอยู่ใน STDIN มากกว่า sdX แม้ว่า)