Tôi có ổ cứng chứa đầy số không.
Làm thế nào để kiểm tra xem tất cả các bit trên ổ cứng có phải là số không bằng cách sử dụng bash không?
Tôi có ổ cứng chứa đầy số không.
Làm thế nào để kiểm tra xem tất cả các bit trên ổ cứng có phải là số không bằng cách sử dụng bash không?
Câu trả lời:
od
sẽ thay thế các hoạt động tương tự *
, vì vậy bạn có thể dễ dàng sử dụng nó để quét các byte khác không:
$ sudo od /dev/disk2 | head
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
234250000
| head
vào phần cuối của điều đó, để nếu hóa ra ổ đĩa không bằng 0, nó dừng lại sau khi tạo ra đầu ra vừa đủ để hiển thị thực tế, thay vì đổ toàn bộ ổ đĩa vào màn hình.
Tôi đã viết một chương trình C ++ ngắn để làm như vậy, nguồn có sẵn ở đây .
Để xây dựng nó:
wget -O iszero.cpp https://gist.github.com/BobVul/5070989/raw/2aba8075f8ccd7eb72a718be040bb6204f70404a/iszero.cpp
g++ -o iszero iszero.cpp
Để chạy nó:
dd if=/dev/sdX 2>/dev/null | ./iszero
Nó sẽ xuất vị trí và giá trị của bất kỳ byte nào khác. Bạn có thể chuyển hướng đầu ra này đến một tệp với >
, ví dụ:
dd if=/dev/sdX 2>/dev/null | ./iszero >nonzerochars.txt
Bạn có thể muốn thử thay đổi BUFFER_SIZE
để có hiệu quả tốt hơn. Tôi không chắc giá trị tối ưu có thể là bao nhiêu. Lưu ý rằng điều này cũng ảnh hưởng đến tần suất in tiến trình, điều này sẽ ảnh hưởng đến tốc độ phần nào (đầu ra in ra bàn điều khiển chậm ). Thêm vào 2>/dev/null
để thoát khỏi đầu ra tiến độ.
Tôi biết rằng đây không phải là sử dụng bash tiêu chuẩn, thậm chí là nội dung, nhưng nó không yêu cầu bất kỳ đặc quyền bổ sung nào. Giải pháp của @Hennes vẫn nhanh hơn (tôi chưa thực sự tối ưu hóa bất cứ điều gì - đây là giải pháp ngây thơ); tuy nhiên, chương trình nhỏ này có thể cho bạn ý tưởng tốt hơn về việc cần gạt của bạn bao nhiêu byte và ở vị trí nào. Nếu bạn tắt đầu ra tiến độ, nó vẫn sẽ nhanh hơn hầu hết các ổ cứng tiêu dùng có thể đọc (> 150 MB / s), vì vậy đó không phải là vấn đề lớn.
Một phiên bản nhanh hơn với đầu ra ít dài hơn có sẵn ở đây . Tuy nhiên, nó vẫn chậm hơn một chút so với giải pháp của @Hennes. Tuy nhiên, cái này sẽ thoát khỏi ký tự khác đầu tiên mà nó gặp phải, vì vậy nó có khả năng nhanh hơn nhiều nếu có một số khác ở gần đầu luồng.
Thêm nguồn vào bài đăng để giữ câu trả lời tốt hơn khép kín:
#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
thay vì yêu cầu nó phải được xử lý bằng một cái gì đó như thế iszero < /dev/sda
nào không?
int main(int argc, char *argv[])
và sau đó FILE* file = fopen(argv[1], "r");
. Hoàn thành đúng cách bao gồm kiểm tra xem đối số có thực sự tồn tại không, kiểm tra lỗi mở thành công (thực hiện ferror
kiểm tra bổ sung sau fopen
), v.v., nhưng quá nhiều rắc rối cho chương trình vứt bỏ.
gcc
không nhất thiết phải có sẵn trên tất cả các bản phân phối Linux mà không cần kéo xuống các gói bổ sung. Sau đó, một lần nữa numpy không phải là một phần của các gói Python tiêu chuẩn ...
-O3
và -march=native
bạn có thể thấy một số tăng tốc; điều đó sẽ đảm bảo GCC cho phép tự động hóa và sử dụng tốt nhất có sẵn cho CPU hiện tại của bạn (AVX, SSE2 / SSE3, v.v.). Cùng với đó bạn có thể chơi với kích thước bộ đệm; kích thước bộ đệm khác nhau có thể tối ưu hơn với các vòng được véc tơ (tôi sẽ chơi với 1MB +, hiện tại là 1kB).
@Bob
) trong trò chuyện: chat.stackexchange.com/rooms/118/root-access
Mở rộng câu trả lời của Gordon, pv
cung cấp một dấu hiệu cho thấy quá trình này kéo dài bao xa:
$ 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
Đây có vẻ là một giải pháp kém hiệu quả, nhưng nếu bạn chỉ phải kiểm tra một lần:
dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
Sử dụng dd để đọc từ đĩa sdX
. (thay thế X bằng ổ đĩa bạn muốn đọc từ đó), sau
đó dịch tất cả các byte không thể in thành một thứ chúng ta có thể xử lý.
Tiếp theo, chúng ta sẽ đếm các byte mà chúng ta có thể xử lý và kiểm tra xem đó có phải là số đúng không (sử dụng wc -c
cho điều đó) hoặc chúng ta bỏ qua việc đếm và sử dụng -s
hoặc --squeeze-repeats
để nén tất cả nhiều lần xuất hiện trong một char.
Do đó dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
chỉ nên in một chữ T.
Nếu bạn muốn làm điều này thường xuyên thì bạn muốn một cái gì đó hiệu quả hơn.
Nếu bạn muốn làm điều này chỉ một lần thì loại bùn này có thể xác minh rằng cần gạt nước bình thường của bạn đang hoạt động và bạn có thể tin tưởng nó.
Để chỉ kiểm tra, bạn sẽ thấy bất kỳ khối nào không khớp với danh sách
sudo badblocks -sv -t 0x00 /dev/sdX
Hoặc sử dụng badblocks để viết chúng cũng như kiểm tra:
sudo badblocks -svw -t 0x00 /dev/sdX
Thử nghiệm phá hủy mặc định là lựa chọn xóa an toàn của tôi
sudo badblocks -svw /dev/sdX
Nếu bất cứ ai cũng có thể lấy bất cứ thứ gì sau khi lấp đầy ổ đĩa bằng 0 và 1 xen kẽ, sau đó bổ sung của họ, sau đó tất cả 1, sau đó tất cả 0, với mỗi lần xác minh nó đã hoạt động, chúc may mắn cho họ!
Làm cho một kiểm tra trước khi triển khai tốt trên các ổ đĩa mới
man badblocks
cho các lựa chọn khác
Không nói là nhanh, nhưng nó hoạt động ...
Một thời gian trước tôi đã tò mò về AIO
. Kết quả là một chương trình thử nghiệm mẫu xảy ra để kiểm tra các sector (khối 512 byte) NUL
. Bạn có thể thấy đây là một biến thể của trình phát hiện vùng tệp thưa thớt . Tôi nghĩ rằng nguồn nói lên tất cả.
NUL
đầu ra trông như thế nào 0000000000-eof
. Lưu ý rằng có một mẹo trong chương trình, chức năng fin()
không được gọi ở dòng 107 nhằm mục đích đưa ra đầu ra được hiển thị.AIO
nó không đơn giản như các cách khác,AIO
là có lẽ là cách nhanh nhất để giữ một đọc bận rộn ổ , bởi vì NUL
so sánh được thực hiện trong khi khối dữ liệu tiếp theo được đọc trong. (Chúng ta có thể bóp ra một vài mili giây nhiều hơn bằng cách thực hiện chồng chéo AIO
, nhưng tôi thực sự không nghĩ rằng đây là giá trị cố gắng.)true
nếu tập tin có thể đọc được và mọi thứ đều hoạt động. Nó không trả về false
nếu tập tin không NUL
.NUL
nó vẫn hoạt động, vì bộ đệm đã chứa NUL
. Nếu ai đó nghĩ rằng điều này cần sửa chữa, trong dòng 95 memcmp(nullblock, buf+off, SECTOR)
có thể đọc memcmp(nullblock, buf+off, len-off<SECTOR : len-off : SECTOR)
. Nhưng sự khác biệt duy nhất là, "báo cáo kết thúc" có lẽ là một chút ngẫu nhiên (không phải cho một tệp hoàn toàn NUL
).memcmp()
cũng khắc phục một sự cố khác trên các nền tảng, không khắc phục được NUL
alloc()
bộ nhớ, vì mã không thực hiện được. Nhưng điều này chỉ có thể được nhìn thấy bởi các tệp dưới 4 MiB, nhưng checknul
có lẽ là quá mức cần thiết cho một nhiệm vụ nhỏ như vậy;)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;
}
Muốn đăng giải pháp thông minh này từ một câu hỏi tương tự nhưng trước đó, được đăng bởi một người dùng chưa đăng nhập trong một thời gian:
Có một thiết bị
/dev/zero
trên hệ thống Linux luôn cung cấp số không khi đọc.Vì vậy, làm thế nào về việc so sánh ổ cứng của bạn với thiết bị này:
cmp /dev/sdX /dev/zero
Nếu tất cả đều ổn với việc loại bỏ ổ cứng của bạn, nó sẽ chấm dứt với:
cmp: EOF on /dev/sdb
nói với bạn rằng hai tệp giống nhau cho đến khi hết ổ cứng. Nếu có một bit khác không trên ổ cứng
cmp
sẽ cho bạn biết nó nằm ở đâu trong tệp.Nếu bạn đã
pv
cài đặt gói thì:pv /dev/sdX | cmp /dev/zero
sẽ làm điều tương tự với một thanh tiến trình để giữ cho bạn thích thú trong khi nó kiểm tra ổ đĩa của bạn (EOF bây giờ sẽ ở trên STDIN chứ không phải là sdX).