Sıfırlarla dolu sabit diskim var.
Sabit diskteki tüm bitlerin bash kullanarak sıfır olup olmadığını nasıl kontrol edebilirim?
Sıfırlarla dolu sabit diskim var.
Sabit diskteki tüm bitlerin bash kullanarak sıfır olup olmadığını nasıl kontrol edebilirim?
Yanıtlar:
od
aynı şeyin çalışmalarını yerine koyar *
, böylece sıfır olmayan bayt taraması için kolayca kullanabilirsiniz:
$ sudo od /dev/disk2 | head
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
234250000
| head
sonuna, sürücünün sıfırlanmadığı ortaya çıkarsa, tüm sürücüyü ekrana dökmek yerine, gerçeği göstermek için yeterli çıktı ürettikten sonra durur.
Bunu yapmak için kısa bir C ++ programı yazdım, kaynak burada mevcut .
İnşa etmek için:
wget -O iszero.cpp https://gist.github.com/BobVul/5070989/raw/2aba8075f8ccd7eb72a718be040bb6204f70404a/iszero.cpp
g++ -o iszero iszero.cpp
Çalıştırmak için:
dd if=/dev/sdX 2>/dev/null | ./iszero
Sıfır olmayan baytların konumunu ve değerini çıktılar. Bu çıktıyı aşağıdaki gibi bir dosyaya yönlendirebilirsiniz >
:
dd if=/dev/sdX 2>/dev/null | ./iszero >nonzerochars.txt
Daha BUFFER_SIZE
iyi verimlilik için değiştirmeyi denemek isteyebilirsiniz . Optimum değerin ne olabileceğinden emin değilim. Bunun ilerlemeyi ne sıklıkta yazdırdığını da etkiler; bu da hızı biraz etkiler (konsola yazdırma çıktısı yavaştır ). Ekle 2>/dev/null
ilerleme çıkışı kurtulmak için.
Bunun standart bash ve hatta builtin kullanmadığının farkındayım, ancak ekstra ayrıcalık gerektirmemelidir. @Hennes'ın çözümü hala daha hızlı (Gerçekten hiçbir şeyi optimize etmedim - bu naif çözümdür); ancak, bu küçük program silicinizin kaç bayt kaçırdığını ve hangi konumda olduğunu daha iyi bir fikir verebilir. İlerleme çıkışını devre dışı bırakırsanız, çoğu sabit sürücünün okuyabileceğinden (> 150 MB / sn) daha hızlı olacaktır, bu büyük bir sorun değildir.
Daha az ayrıntılı çıktıya sahip daha hızlı bir sürüm burada mevcuttur . Ancak, hala @Hennes'ın çözümünden biraz daha yavaş. Bununla birlikte, bu, karşılaştığı ilk sıfır olmayan karakterden çıkacaktır, bu nedenle akışın başlangıcına yakın bir sıfır olmayan varsa potansiyel olarak çok daha hızlıdır.
Cevabı daha iyi tutmak için yayına kaynak eklemek:
#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
şeyle pipetlenmesini gerektirmek yerine iszero < /dev/sda
?
int main(int argc, char *argv[])
sonra ve FILE* file = fopen(argv[1], "r");
. Düzgün bir şekilde yapıldığında, argümanın gerçekten var olup olmadığını kontrol etme, başarılı bir şekilde açma kontrolü ( ferror
sonra ek bir kontrol yapın fopen
) vb., Ancak bir bırakma programı için çok fazla sorun bulunur.
gcc
ek paketler çekilmeden tüm Linux dağıtımlarında zorunlu olarak bulunmamasıdır. Sonra tekrar numpy standart Python paketlerinin bir parçası değil ...
-O3
ve -march=native
bazı hızlanmalar görebilirsiniz; GCC'nin otomatik vektörleştirmeyi etkinleştirdiğinden ve mevcut CPU'nuz için (AVX, SSE2 / SSE3 vb.) mümkün olan en iyisini kullandığından emin olmalıdır. Bununla birlikte tampon boyutu ile oynayabilirsiniz; farklı tampon boyutları vektörleştirilmiş döngülerle daha uygun olabilir (1MB + ile oynarım, mevcut olan 1kB'dir).
@Bob
sohbette bana ( ) ping atabilirsiniz
Gordon'un cevabına pv
genişlemek, süreç boyunca ne kadar uzak olduğunun bir göstergesidir:
$ 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
Bu çirkin verimsiz bir çözüm gibi görünüyor, ancak sadece bir kez kontrol etmeniz gerekiyorsa:
dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
Diskten okumak için dd kullanma sdX
. (okumak için kullanmak istediğiniz sürücü ile X yerine)
Sonra tercüme biz işleyebilir şeye tüm yazdırılamayan sıfır bayt.
Daha sonra, işleyebileceğimiz baytları sayarız ve doğru sayı olup olmadığını kontrol ederiz ( wc -c
bunun için kullanın ) veya saymayı atlayıp tüm çoklu oluşumları tek bir karaktere sıkıştırmak için -s
veya öğesini --squeeze-repeats
kullanırız.
Bu dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
yüzden sadece tek bir T yazdırmalıdır.
Bunu düzenli olarak yapmak istiyorsanız, daha verimli bir şey istersiniz.
Bunu sadece bir kez yapmak istiyorsanız, bu çamur normal silicinizin çalıştığını ve ona güvenebileceğinizi doğrulayabilir.
Yalnızca kontrol etmek için, listelenmeyen tüm blokları görürsünüz
sudo badblocks -sv -t 0x00 /dev/sdX
Veya bunları yazmak ve kontrol etmek için badblock'ları kullanın:
sudo badblocks -svw -t 0x00 /dev/sdX
Varsayılan yıkıcı test seçimimi güvenli bir şekilde silmem
sudo badblocks -svw /dev/sdX
Herkes sürücüyü 0s ve 1s ile doldurduktan sonra bir şey alabilirse, tamamlayıcıları, sonra tüm 1'ler, daha sonra tüm 0'lar, her geçişle çalıştığını doğruladı, onlara iyi şanslar!
Yeni sürücülerde de iyi bir dağıtım öncesi kontrol yapar
man badblocks
diğer seçenekler için
Hızlı olduğunu söylemiyorum ama işe yarıyor ...
Her iki dünyanın en iyisi. Bu komut bozuk sektörleri atlayacaktır:
sudo dd if=/dev/sdX conv=noerror,sync | od | head
kill -USR1 <pid of dd>
İlerlemeyi görmek için kullanın .
Bir süre önce merak ediyordum AIO
. Sonuç, sektörleri (512 bayt blok) kontrol eden örnek bir test programıdır NUL
. Bunu seyrek bir dosya bölgesi dedektörünün bir çeşidi olarak görebilirsiniz . Bence kaynak her şeyi söylüyor.
NUL
çıktısı gibi görünür 0000000000-eof
. Programda bir hile olduğuna dikkat edin, fin()
gösterilen çıktıyı vermek amacıyla fonksiyon 107 satırında çağrılmaz.AIO
çünkü diğer yollar kadar basit değildir,AIO
olan bir tahrik meşgul okumaya devam etmenin en hızlı yolu muhtemelen çünkü, NUL
bir sonraki veri bloğu okunduğunda ise yapılır karşılaştırın. (Biz örtüşen yaparak birkaç milisaniye sıkmak AIO
, ama gerçekten bu değer olduğunu düşünmüyorum çaba.)true
Dosya okunabilirse ve her şey işe yaradıysa her zaman geri döner . false
Dosya olmayan ise geri dönmez NUL
.NUL
bellek arabellekleri zaten içerdiği için tamamen çalışır NUL
. Birisi bunun bir düzeltmeye ihtiyacı olduğunu düşünürse, 95. satırda memcmp(nullblock, buf+off, SECTOR)
okuyabilir memcmp(nullblock, buf+off, len-off<SECTOR : len-off : SECTOR)
. Ama tek fark "son raporlama" belki de (değil tamamen bir dosya için raslantısaldır yani, NUL
).memcmp()
bulunmayan platformlardaki başka bir sorunu da giderir NUL
alloc()
. Ancak bu sadece 4 MiB'den daha az olan dosyalar tarafından görülebilir, ancak checknul
muhtemelen bu kadar küçük bir görev için aşırı derecede aşırıdır;)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;
}
Bu akıllı çözümü , bir süredir oturum açmamış bir kullanıcı tarafından gönderilen benzer ancak daha önceki bir sorudan göndermek istedi :
/dev/zero
Linux sisteminde okunduğunda daima sıfır veren bir cihaz vardır .Peki, sabit sürücünüzü bu cihazla karşılaştırmaya ne dersiniz:
cmp /dev/sdX /dev/zero
Sabit diskinizi sıfırlamakla her şey yolundaysa, aşağıdakilerle sona erecektir:
cmp: EOF on /dev/sdb
size iki dosyanın sabit sürücünün sonuna kadar aynı olduğunu söyler. Sabit sürücüde sıfır olmayan bir bit
cmp
varsa, dosyanın nerede olduğunu söyler.Eğer varsa
pv
paket daha sonra yüklü:pv /dev/sdX | cmp /dev/zero
sürücünüzü kontrol ederken sizi eğlendirmek için bir ilerleme çubuğu ile aynı şeyi yapacak (EOF şimdi sdX yerine STDIN'de olacak).