ゼロでいっぱいのハードドライブがあります。
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 MB / s)よりも高速なので、それは大きな問題ではありません。
より詳細な出力を備えたより高速なバージョンはこちらから入手できます。ただし、@ 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で自動ベクトル化が有効になり、現在のCPU(AVX、SSE2 / SSE3など)で利用可能な最適なものが使用されるようになります。それに加えて、バッファサイズで遊ぶことができます。ベクトル化されたループでは、さまざまなバッファサイズがより最適な場合があります(1MB +で再生します。現在のバッファサイズは1kBです)。
@Bob
、チャットでping()できます:chat.stackexchange.com/rooms/118/root-access
Gordonの答えを拡張する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
を使用して複数のオカレンスをすべて1つの文字に絞り込みます。
したがってdd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
、単一のTのみを印刷する必要があります。
これを定期的に行いたい場合は、より効率的な何かが必要です。
これを1回だけ行いたい場合、このクラッジは、通常のワイパーが機能していることと、信頼できることを確認する場合があります。
チェックのみを行うには、一致しないブロックがリストされます
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()
、コードが実行しないため、メモリを編集しません。しかし、これは4 MiB未満のファイルでのみ見られる場合がありますが、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
ハードドライブの最後に到達するまで、2つのファイルは同じであることを伝えます。ハードドライブにゼロ以外のビットがある場合
cmp
、ファイル内のどこにあるかがわかります。あなたが持っている場合は
pv
、パッケージをインストールした後:pv /dev/sdX | cmp /dev/zero
ドライブをチェックしている間、面白さを保つためにプログレスバーで同じことを行います(ただし、EOFはsdXではなくSTDINになります)。