У меня жесткий диск заполнен нулями.
Как проверить, что все биты на жестком диске являются нулями, используя 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 без удаления дополнительных пакетов. С другой стороны, numpy также не является частью стандартных пакетов 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"
следует печатать только один T.
Если вы хотите делать это регулярно, то вы хотите что-то более эффективное.
Если вы хотите сделать это только один раз, тогда этот кладж может проверить, работает ли ваш обычный стеклоочиститель и можете ли вы доверять ему.
Только для проверки вы увидите все блоки, которые не соответствуют перечисленным
sudo badblocks -sv -t 0x00 /dev/sdX
Или используйте badblocks, чтобы написать их, а также проверить:
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()
редактируют память, потому что код этого не делает. Но это может быть видно только для файлов checknul
размером менее 4 МБ, но, вероятно, это просто излишество для такой маленькой задачи;)НТН
/* 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).