У мене жорсткий диск, заповнений нулями.
Як перевірити, чи всі біти на жорсткому диску є нулями з використанням 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
щоб позбутися результатів прогресу.
Я знаю, що це не використання стандартного bash, ні навіть вбудованих програм, але це не повинно вимагати додаткових привілеїв. Рішення @Hennes все ще швидше (я насправді нічого не оптимізував - це наївне рішення); однак ця маленька програма може дати вам краще уявлення про те, скільки байтів пропустив склоочисник і в якому місці. Якщо ви вимкнете висновок прогресу, він все ще буде швидшим, ніж більшість споживчих жорстких дисків, які він може прочитати (> 150 Мб / с), тому це не велика проблема.
Більш швидка версія з менш багатослівним виходом доступна тут . Однак це все-таки трохи повільніше, ніж рішення @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, не знімаючи додаткових пакетів. Тоді знову нуме не входить до стандартних пакетів Python ...
-O3
і -march=native
, можливо, ви побачите деякі прискорення; це повинно переконатися, що GCC дозволяє автоматичну векторизацію та використовує найкращі для вашого поточного процесора (AVX, SSE2 / SSE3 тощо). Поряд з цим ви можете грати з розміром буфера; різні розміри буфера можуть бути більш оптимальними для векторизованих циклів (я б грав з 1 МБ +, поточний - 1 КБ).
@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
Або використовуйте чорні блоки, щоб написати їх, а також перевірити:
sudo badblocks -svw -t 0x00 /dev/sdX
Тест на деструктивність за замовчуванням - це моє безпечне стирання вибору
sudo badblocks -svw /dev/sdX
Якщо хтось може отримати що-небудь після заповнення накопичувача з чергуванням 0 і 1, то їх доповнення, потім усі 1, потім усі 0, з кожним проходом перевірено, що це спрацювало, удачі!
Здійснює хорошу перевірку перед розміщенням і на нових дисках
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()
éd пам'яті, тому що код не робить. Але це може бути помічено лише файлами, меншими за 4 Мб, але, checknul
ймовірно, це зайвий надмір для такої невеликої задачі;)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).