Ich habe eine Festplatte mit Nullen gefüllt.
Wie kann man mit bash überprüfen, ob alle Bits auf der Festplatte Nullen sind?
Ich habe eine Festplatte mit Nullen gefüllt.
Wie kann man mit bash überprüfen, ob alle Bits auf der Festplatte Nullen sind?
Antworten:
od
ersetzt Läufe derselben Sache durch *
, sodass Sie problemlos nach Bytes ungleich Null suchen können:
$ sudo od /dev/disk2 | head
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
234250000
| head
, dass, wenn sich herausstellt, dass das Laufwerk nicht auf Null gesetzt ist, es stoppt, nachdem gerade genug Ausgabe erzeugt wurde, um die Tatsache zu zeigen, anstatt das gesamte Laufwerk auf dem Bildschirm auszugeben.
Ich habe dazu ein kurzes C ++ - Programm geschrieben, den Quellcode finden Sie hier .
Um es zu bauen:
wget -O iszero.cpp https://gist.github.com/BobVul/5070989/raw/2aba8075f8ccd7eb72a718be040bb6204f70404a/iszero.cpp
g++ -o iszero iszero.cpp
Um es auszuführen:
dd if=/dev/sdX 2>/dev/null | ./iszero
Es wird die Position und den Wert aller Bytes ungleich Null ausgegeben. Sie können diese Ausgabe in eine Datei umleiten >
, z. B .:
dd if=/dev/sdX 2>/dev/null | ./iszero >nonzerochars.txt
Möglicherweise möchten Sie Änderungen BUFFER_SIZE
vornehmen, um die Effizienz zu verbessern. Ich bin nicht sicher, was ein optimaler Wert sein könnte. Beachten Sie, dass dies auch die Häufigkeit des Druckvorgangs beeinflusst, was sich etwas auf die Geschwindigkeit auswirkt (die Druckausgabe an die Konsole ist langsam ). Hinzufügen 2>/dev/null
, um die Fortschrittsausgabe zu entfernen.
Mir ist bewusst, dass dies weder Standard-Bash noch integrierte Funktionen verwendet, es sollten jedoch keine zusätzlichen Berechtigungen erforderlich sein. Die Lösung von @Hennes ist immer noch schneller (ich habe nichts wirklich optimiert - das ist die naive Lösung); Dieses kleine Programm kann Ihnen jedoch eine bessere Vorstellung davon geben, wie viele Bytes Ihr Wischer verpasst hat und an welcher Stelle. Wenn Sie die Fortschrittsausgabe deaktivieren, ist sie immer noch schneller als die meisten herkömmlichen Festplatten (> 150 MB / s). Dies ist also kein großes Problem.
Eine schnellere Version mit weniger ausführlicher Ausgabe ist hier verfügbar . Es ist jedoch immer noch etwas langsamer als die Lösung von @Hennes. Dieses wird jedoch beim ersten Zeichen, das nicht Null ist, beendet, sodass es möglicherweise viel schneller ist, wenn sich am Anfang des Streams ein Wert ungleich Null befindet.
Hinzufügen einer Quelle zum Posten, um die Antwort in sich geschlossener zu halten:
#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
dass es eher wie ein normaler Befehl funktioniert - mit etwas anderem als mit etwas, das mit etwas weitergeleitet werden muss iszero < /dev/sda
?
int main(int argc, char *argv[])
und dann FILE* file = fopen(argv[1], "r");
. Bei ordnungsgemäßer Ausführung wird u. A. Überprüft, ob das Argument tatsächlich vorhanden ist, ob das Öffnen erfolgreich war (führen ferror
Sie nach dem eine zusätzliche Überprüfung durch fopen
) usw. Für ein Wegwerfprogramm ist dies jedoch zu schwierig.
gcc
Ist, dass es im Allgemeinen ohne Compiler verfügbar und lauffähig ist, während es nicht unbedingt auf allen Linux-Distributionen verfügbar ist, ohne dass zusätzliche Pakete heruntergeladen werden müssen. Andererseits ist numpy auch nicht Teil von Standard-Python-Paketen ...
-O3
und -march=native
möglicherweise einige Beschleunigungen sehen; Das sollte sicherstellen, dass GCC die automatische Vektorisierung aktiviert und das Beste für Ihre aktuelle CPU verwendet (AVX, SSE2 / SSE3 usw.). Außerdem können Sie mit der Puffergröße spielen. Unterschiedliche Puffergrößen sind bei vektorisierten Schleifen möglicherweise optimaler (ich würde mit 1 MB + spielen, die aktuelle Größe ist 1 KB).
Die Antwort von Gordon gibt Aufschluss darüber, pv
wie weit der Prozess fortgeschritten ist:
$ 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
Dies scheint eine hässliche ineffiziente Lösung zu sein, aber wenn Sie nur einmal prüfen müssen:
dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
Verwenden von dd zum Lesen von der Festplatte sdX
. (ersetzen Sie die X mit dem Laufwerk , von dem Sie lesen wollen),
dann übersetzen alle nicht druckbaren Null - Bytes zu etwas , das wir verarbeiten kann.
Als Nächstes zählen wir entweder die Bytes, die wir verarbeiten können, und prüfen, ob es die richtige Zahl ist (verwenden Sie sie wc -c
dafür), oder wir überspringen die Zählung und verwenden -s
oder --squeeze-repeats
, um alle mehrfachen Vorkommen zu einem einzelnen Zeichen zusammenzufassen.
Daher dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
sollte nur ein einziges T ausgegeben werden.
Wenn Sie dies regelmäßig tun möchten, möchten Sie etwas effizienteres.
Wenn Sie dies nur einmal tun möchten, kann dieser Fehler bestätigen, dass Ihr normaler Wischer funktioniert und Sie ihm vertrauen können.
Um nur zu überprüfen, sehen Sie alle Blöcke, die nicht übereinstimmen, aufgelistet
sudo badblocks -sv -t 0x00 /dev/sdX
Oder benutze Badblocks, um sie zu schreiben und zu überprüfen:
sudo badblocks -svw -t 0x00 /dev/sdX
Der voreingestellte destruktive Test ist das sichere Löschen meiner Wahl
sudo badblocks -svw /dev/sdX
Wenn irgendjemand etwas abrufen kann, nachdem er das Laufwerk mit abwechselnden Nullen und Einsen gefüllt hat, dann sein Komplement, dann alle Einsen, dann alle Nullen, und bei jedem bestätigten Durchgang hat es funktioniert, viel Glück für sie!
Führt auch bei neuen Laufwerken eine gute Überprüfung vor der Bereitstellung durch
man badblocks
für andere Optionen
Das heißt nicht, dass es schnell ist, aber es funktioniert ...
Beste aus beiden Welten. Dieser Befehl überspringt fehlerhafte Sektoren:
sudo dd if=/dev/sdX conv=noerror,sync | od | head
Verwenden Sie kill -USR1 <pid of dd>
, um den Fortschritt zu sehen.
Vor einiger Zeit war ich neugierig AIO
. Das Ergebnis war ein Probentestprogramm , das für die Sektoren (512 - Byte - Blöcke) , die zu überprüfen sind passiert NUL
. Sie können dies als eine Variante eines Detektors für dünn besetzte Dateibereiche betrachten . Ich denke, die Quelle sagt alles.
NUL
ausgegeben wird, sieht das so aus 0000000000-eof
. Beachten Sie, dass das Programm einen Trick enthält. Die Funktion fin()
wird in Zeile 107 nicht absichtlich aufgerufen, um die angezeigte Ausgabe zu erhalten.AIO
nicht so einfach ist wie andere Möglichkeiten.AIO
ist jedoch wahrscheinlich der schnellste Weg, um ein Laufwerk mit dem Lesen zu beschäftigen , da der NUL
Vergleich ausgeführt wird, während der nächste Datenblock eingelesen AIO
wird Anstrengung.)true
wenn die Datei lesbar ist und alles funktioniert hat. Es wird nicht zurückgegeben, false
wenn die Datei nicht vorhanden ist NUL
.NUL
funktioniert er jedoch weiterhin, da die Speicherpuffer bereits enthalten NUL
. Wenn jemand der Meinung ist, dass dies behoben werden muss, könnte in Zeile 95 memcmp(nullblock, buf+off, SECTOR)
gelesen werden memcmp(nullblock, buf+off, len-off<SECTOR : len-off : SECTOR)
. Der einzige Unterschied ist jedoch, dass die "Endberichterstattung" möglicherweise etwas zufällig ist (nicht für eine Datei, die vollständig ist NUL
).memcmp()
behebt auch ein anderes Problem auf Plattformen, die keinen NUL
alloc()
Arbeitsspeicher haben, da der Code dies nicht tut. Dies kann aber nur bei Dateien mit weniger als 4 MiB auftreten, ist aber checknul
für eine so kleine Aufgabe wahrscheinlich ein reiner 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;
}
Wollte diese clevere Lösung aus einer ähnlichen, aber früheren Frage posten , die von einem Benutzer gestellt wurde, der sich längere Zeit nicht angemeldet hat:
Auf
/dev/zero
einem Linux-System gibt es ein Gerät , das beim Lesen immer Nullen gibt.Wie wäre es also mit einem Vergleich Ihrer Festplatte mit diesem Gerät:
cmp /dev/sdX /dev/zero
Wenn alles in Ordnung ist, wenn Sie Ihre Festplatte auf Null setzen, wird sie beendet mit:
cmp: EOF on /dev/sdb
Sie werden darauf hingewiesen, dass die beiden Dateien bis zum Ende der Festplatte identisch sind. Wenn sich auf der Festplatte ein Bit ungleich Null befindet,
cmp
werden Sie darüber informiert, wo es sich in der Datei befindet.Wenn Sie das
pv
Paket installiert haben, dann:pv /dev/sdX | cmp /dev/zero
Das Gleiche geschieht mit einem Fortschrittsbalken, um Sie bei der Überprüfung Ihres Laufwerks zu unterhalten (das EOF befindet sich jetzt jedoch auf STDIN und nicht auf sdX).