하드 드라이브에 0이 채워져 있습니다.
bash를 사용하여 하드 드라이브의 모든 비트가 0인지 확인하는 방법은 무엇입니까?
하드 드라이브에 0이 채워져 있습니다.
bash를 사용하여 하드 드라이브의 모든 비트가 0인지 확인하는 방법은 무엇입니까?
답변:
od
같은 실행을로 대체 *
하므로 0을 사용하지 않는 바이트를 쉽게 스캔 할 수 있습니다.
$ sudo od /dev/disk2 | head
0000000 000000 000000 000000 000000 000000 000000 000000 000000
*
234250000
| head
는 드라이브가 제로 불가능한 것으로 판명되는 경우,이 사실을 보여주기 위해 충분한 출력을 생성, 대신 화면 전체 드라이브를 덤프 후 중지 그래서, 그 끝에.
그렇게하기 위해 짧은 C ++ 프로그램을 작성했습니다 . 소스는 here .
그것을 구축하려면 :
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
0이 아닌 바이트의 위치와 값을 출력합니다. 다음을 사용하여이 출력을 파일로 리디렉션 할 수 있습니다 >
.
dd if=/dev/sdX 2>/dev/null | ./iszero >nonzerochars.txt
BUFFER_SIZE
더 나은 효율성 을 위해 변경을 시도 할 수 있습니다 . 최적의 값이 무엇인지 잘 모르겠습니다. 이것은 또한 진행률을 인쇄하는 빈도에 영향을 미치며 속도에 다소 영향을 미칩니다 (콘솔에 출력하는 속도가 느림 ). 2>/dev/null
진행률 출력을 제거하려면 추가하십시오 .
나는 이것이 표준 bash 또는 내장을 사용하지 않는다는 것을 알고 있지만 추가 권한이 필요하지 않습니다. @Hennes의 솔루션은 여전히 더 빠릅니다 (실제로 아무것도 최적화하지 않았습니다-이것은 순진한 솔루션입니다). 그러나이 작은 프로그램은 와이퍼가 몇 바이트를 놓쳤는 지, 어떤 위치에서 더 나은 아이디어를 제공 할 수 있습니다. 진행률 출력을 비활성화하면 여전히 대부분의 소비자 용 하드 드라이브가 읽을 수있는 것보다 빠릅니다 (> 150MB / s). 그리 큰 문제는 아닙니다.
보다 자세한 출력이 적은 더 빠른 버전이 여기에 있습니다 . 그러나 여전히 @Hennes '솔루션보다 약간 느립니다. 그러나 이것은 0이 아닌 첫 번째 문자에서 종료되므로 스트림의 시작 부분 근처에 0이 아닌 문자가 있으면 잠재적으로 훨씬 빠릅니다.
더 나은 독립성을 유지하기 위해 게시 할 소스 추가 :
#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도 표준 파이썬 패키지의 일부가 아닙니다.
-O3
및 -march=native
일부 속도 향상을 볼 수 있습니다; 이를 통해 GCC가 자동 벡터화를 활성화하고 현재 CPU (AVX, SSE2 / SSE3 등)에 가장 적합한 것을 사용해야합니다. 그와 함께 버퍼 크기로 재생할 수 있습니다. 다른 버퍼 크기는 벡터화 루프에서 더 최적 일 수 있습니다 (1MB 이상으로 재생, 현재는 1kB 임).
@Bob
) 채팅을 : 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를 읽으려는 드라이브로 바꾸십시오)
그런 다음 인쇄 할 수없는 모든 0 바이트를 처리 할 수있는 것으로 변환 하십시오.
우리는 하나 계산 다음으로는 우리가 처리하고 그것이 바로 수 (사용 있는지 확인 할 수 바이트 wc -c
그 경우), 또는 우리가 계산을 건너 뛰고을 사용 -s
하거나 --squeeze-repeats
하나의 문자에 모든 여러 번 짜내.
따라서 dd if=/dev/sdX | tr --squeeze-repeats "\000" "T"
단일 T 만 인쇄해야합니다.
이 작업을 정기적으로 수행하려면보다 효율적인 것을 원하십시오.
이 작업을 한 번만 수행하려면이 kludge가 정상적인 와이퍼가 작동하고 있으며 신뢰할 수 있는지 확인할 수 있습니다.
확인하기 만하면 일치하지 않는 블록이 나열됩니다.
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()
은 코드가 수행하지 않기 때문에 메모리가 부족한 플랫폼의 다른 문제도 해결 합니다. 그러나 이것은 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 시스템에는 읽을 때 항상 0을 제공 하는 장치가 있습니다 .따라서 하드 드라이브와이 장치를 비교하는 방법은 다음과 같습니다.
cmp /dev/sdX /dev/zero
모든 것이 하드 드라이브의 제로 아웃에 성공하면 다음과 같이 종료됩니다.
cmp: EOF on /dev/sdb
하드 드라이브의 끝까지 두 파일이 동일하다는 것을 알려줍니다. 하드 드라이브에 0이 아닌 비트가 있으면
cmp
파일의 어디에 있는지 알려줍니다.당신이있는 경우
pv
패키지는 설치 :pv /dev/sdX | cmp /dev/zero
드라이브를 확인하는 동안 즐겁게 진행하기 위해 진행률 표시 줄과 동일한 작업을 수행합니다 (EOF는 이제 sdX가 아닌 STDIN에 있습니다).