장치의 시작 부분을 임의의 비트나 0으로 덮어쓰려면 어떻게 해야 합니까?

장치의 시작 부분을 임의의 비트나 0으로 덮어쓰려면 어떻게 해야 합니까?

단지 장치의 작은 부분을 0이나 임의의 비트로 덮고 싶을 뿐입니다. 보다 정확하게는 모든 섹터의 처음 1% 또는 몇 MiB를 다루고 싶습니다. 이를 수행하는 쉬운 방법이 있습니까?

답변1

매우 느리기 때문에 /dev/urandom많은 양의 데이터(전체 디스크)를 처리하는 데는 적합하지 않지만 작은 영역에는 적합할 수 있습니다.

8MiB를 다루는 예:

dd bs=1M count=8 iflag=fullblock if=/dev/urandom of=/dev/destroyme

또는 다음을 사용할 수 있습니다 shred.

shred -v -n 1 -s 8M /dev/destroyme

또한 losetup특정 크기 및 오프셋의 장치를 생성하고 자체 크기/오프셋 옵션이 없는 유틸리티를 사용하여 이를 재정의할 수도 있습니다.

losetup --find --show --offset 0 --sizelimit $((8*1024*1024)) /dev/destroyme
# will print /dev/loopX
cat /dev/urandom > /dev/loopX
losetup -d /dev/loopX

답변2

다른 파일과 마찬가지로 처음 10MiB를 0으로 덮어씁니다.

head -c10M < /dev/zero 1<> /dev/sdax

블록 장치 파일의 경우 1<>잘림 없이 열 필요조차 없습니다. 블록 장치 잘림 같은 것이 없기 때문에 다음과 같이 간단하게 수행할 수 있습니다.

head -c10M < /dev/zero > /dev/sdax

모든 헤더 구현이 이것을 지원하는 것은 아니며 -c, 지원하는 경우 모두가 이 M접미사를 지원하는 것은 아닙니다(지원하는 경우 내장 에서처럼 M메가바이트(1000000바이트) 또는 GNU에서처럼 메가바이트(1048576바이트)를 의미할 수 있습니다 ). 이 경우 다음을 수행할 수 있습니다.ksh93headhead

head -c "$((10 * 1024 * 1024)"

확실히 해.

비교해보면 dd bs=1M count=10 < /dev/zero > /dev/sdax:

  • 개념적으로

    • head파일에서 지정된 수의 바이트 또는 라인을 읽고 이를 stdout에 쓰는 명령입니다.
    • while은 dd원하는 방식으로 데이터를 읽고 쓸 수 있는 하위 수준 명령입니다.

    head작업을 위해 설계된 명령이기 때문에 여기서 사용하고 있습니다 . dd특정 사용 사례에 맞게 최적화하거나 특정 기능 중 하나를 사용하려는 경우 dd이를 사용합니다 (이식성에 대한 참고 사항도 참조).

  • 읽기 + 쓰기 루프:

    • head -c10M관계없이 요청된 데이터를 읽으려는 시도가 이루어지며 오류가 발생한 경우 종료 상태가 0이 아닌 경우에만 실패합니다.
    • dd bs=1M count=10, 10번의 읽기가 수행되며(오류가 없는 한), 일부 데이터를 반환하는 읽기마다 읽은 데이터 양을 사용하여 해당 쓰기가 수행됩니다. 이 방법은 각 읽기가 요청된 데이터 1M를 정확히 반환하는 경우에만 작동합니다. 실제로는 맞습니다 /dev/zero. 하지만 Linux(최소 4.6)에서는 /dev/urandom한 번의 읽기로 32MiB에서 1바이트의 데이터를 뺀 것 이상을 얻을 수 없습니다(따라서 1MiB의 경우에는 여전히 괜찮지만 다른 버전인 Linux용 YMMV를 사용하는 경우). , 그리고 의 경우에는 /dev/random몇 바이트(현재 엔트로피 풀에 있는 바이트)만 있습니다. GNU 구현에는 요청 버퍼가 가득 찰 때까지 계속 읽는 동작이 dd있지만 GNU가 없는 경우 유일한 옵션은 한 번에 1바이트 읽기를 수행하는 것인데 이는 성능에 큰 영향을 미칩니다.iflag=fullblockheaddd
  • 성능: 소량의 데이터(수백 메가바이트 미만)(데이터가 나중에 디스크에 플러시되거나 기록될 버퍼에 기록되는 경우) 이외의 모든 경우 /dev/null프로세스는 I/O 바인딩됩니다. 읽기 /dev/urandom또는 /dev/random병목 현상이 발생하는 경우 난수 생성 또는 디스크 I/O가 발생합니다. 이 경우 dd와 head 사이에는 큰 차이가 없습니다. 어떤 경우든 headCPU 오버헤드가 더 높을 가능성이 있습니다(성능이 I/O 바인딩된 경우에는 알 수 없음).

    • head기본적인 도구이다. 구현은 모든 유형의 입력 및 출력에 대해 여전히 안정적이고 너무 많은 리소스를 사용하지 않으면서 가능한 한 효율적으로 작업을 수행하려고 노력합니다. 동일한 읽기+쓰기 루프를 수행합니다 dd. 성능의 주요 차이점은 읽기 및 쓰기 크기이며, 이에 따라 수행된 시스템 호출 수가 결정됩니다.

      이러한 크기는 시스템 구현 및 버전에 따라 다르며 head시스템에 따라 달라질 수 있습니다. 내 시스템에서 최신 버전의 GNU를 사용할 때 head읽기 크기는 BUFSIZE(GNU 시스템에서는 8KiB)이고 쓰기 크기는 4KiB이지만 변경할 수 있습니다 stdbuf -o 1M.

      ksh93내장 head함수는 64KiB 읽기 및 쓰기를 수행하고 적어도 내 시스템에서는 libc의 stdio를 사용하지 않는 것으로 보입니다.

      GNU의 headstdio 사용은 stdio가 추가 오버헤드를 발생시킨다는 것을 의미합니다(구현은 시스템에 따라 다름).

      현재 버전의 GNU는 캐시가 그에 따라 최적화될 수 있도록 데이터를 순차적으로 읽을 것임을 시스템에 알리는 cat데 사용됩니다 . fadvise일부 구현이 head이 작업을 수행할 수 있거나 미래에도 수행할 수 있다는 것은 불가능하지 않습니다. 낮은 수준이기 때문에 사용자가 지시한 경우에만 실행되기를 원합니다( 이러한 지원이 있는 구현 dd은 알지 못합니다 ).dd

    • ddread()매우 낮은 수준으로 직접 호출 및 write()시스템 호출을 수행합니다 . Linux와 같은 특수 API를 사용하는 것 외에는 이보다 훨씬 더 효율적일 수 없습니다 sendfile().

      read()이를 통해 합계 크기를 더 잘 제어할 수 write()있으므로 입력/출력 유형과 사용 가능한 리소스를 기반으로 최적화할 수 있습니다. 예를 들어 여유 메모리가 많다면 한 번에 전체 데이터를 읽는 것이 나을 것입니다. (비록 제가 테스트해 본 결과 /dev/zero에서 /dev로 복사할 때 과거에 비해 크게 개선된 점은 보이지 않았습니다. /null) 크기는 32KiB이며, 블록 크기가 1MiB 이후에도 성능이 떨어지기 시작합니다.

  • 이식성

    -c, bs=10M, 은(는) conv=fullblock이식 가능하지 않습니다. 파일에서 특정 양의 데이터를 읽는 유일한 POSIX 명령은 이지만 dd, 이를 안정적으로 사용하려면( on 제외 /dev/zero) 위에서 언급한 대로 bs=1성능이 좋지 않습니다.

  • 쓰기 오류의 결과.

    블록 장치의 끝을 지나서 쓰려고 하면 head둘 다 즉시 종료됩니다 . dd디스크에 결함이 있는 섹터가 있는 경우 디스크에 대한 실제 쓰기가 비동기식이므로 일반적으로 감지되지 않습니다. GNU 구현을 사용하면 dd직접 쓰기를 강제할 수 있습니다. oflag=direct이는 dd첫 번째 오류에서 중지하는 것을 의미합니다. 첫 번째 실패한 섹터 이전에 최대한 많은 데이터를 쓰려면 기본 블록 크기인 512를 사용할 수 있습니다.

  • 읽기 오류의 결과

    /dev/zero, /dev/urandom 또는 /dev/random에서 읽기 오류가 발생하면 안 됩니다. 그러나 더 일반적으로는 첫 번째 읽기에서 head및 둘 다 dd오류와 함께 종료됩니다. 를 사용하면 dd계속 오류를 사용할 수 있습니다 conv=noerror. 이 경우 실패한 블록을 0으로 채우는 옵션 sync( ) 을 추가할 수 있습니다 . 이는 해당 기능을 위해 설계되지 않았기 때문에 이를 수행할 수 있는 옵션을 제공하지 않습니다.conv=noerror,synchead

대안.

  • pv -Ss 10M < /dev/zero > /dev/sdax10M을 복사하고 진행률 표시줄을 표시합니다. 테스트에서 기본 읽기/쓰기 크기는 128KiB였습니다. options 을 사용하여 이를 변경할 수 있지만 -B내 테스트에서는 128KiB가 최상의 결과를 제공했습니다. s 와 동일한 옵션이 pv있습니다 .-Eddconv=noerror,sync

    Linux에서는 성능을 최적화하기 위해 시스템 호출을 사용하므로 파이프를 통한 I/O도 용이하게 합니다 splice().

  • 시스템 호출을 사용하려면 를 sendfile()사용할 수 있습니다 xfs_io.

    xfs_io -c 'sendfile -i src 0 10M' dst
    

    src에서 dst로 10M 데이터를 보냅니다. 그러나 그것은 단지하나 sendfile()/dev/zero그리고 , /dev/random또는 에서는 시스템 호출을 사용할 수 없습니다 /dev/urandom. 그러나 스파스 파일에는 사용할 수 있습니다.

     truncate -s 1T empty-file
     xfs_io -c 'sendfile -i empty-file 0 10M' /dev/sdax
    

    작동할 수 있지만 대용량(수 기가바이트)의 경우 이는 sendfile()시스템 호출이기 때문에 그만큼의 메모리를 할당해야 하므로 효율성이 떨어집니다 . 이상적으로 는 몇 기가바이트 이상을 수행하고 dd bs=1M싶습니다 . sendfile()시간 바이트 조작을 수행할 수 있지만 이를 수행할 수 있는 명령은 없습니다.

  • 입력을 위해 /dev/zero실제로는 필요하지 않습니다.읽다당신이 쓰는 각 블록에 대한 데이터. 결국 그것은 단지 0입니다. 를 읽지 않고 0만 있는 버퍼를 만드는 것은 쉽고 /dev/zero, 각 쓰기 사이에 이를 재사용할 수 있습니다. 예를 들어:

    PERLIO=:unix perl -e '$x = pack("x" . 1024*1024); print $x for 1..10000' > /dev/sdax
    

perl10000MiB를 쓰는 것은 반복적인 읽기 솔루션보다 더 효율적입니다(오버헤드에도 불구하고) /dev/zero.

답변3

당신은 임의의 데이터를 제공하는 장치를 사용하여 dd이를 수행 할 수 있습니다. /dev/urandom한 가지 예:

dd if=/dev/urandom of=/dev/sdX bs=1M count=100

이렇게 하면 100MB의 임의 데이터가 기록됩니다.

  • if입력 파일입니다
  • of출력 파일입니다
  • bs=1M블록 크기는 1Mbyte입니다.
  • count이 블록은 몇 번이나 작성되어야 합니까?

/dev/zero입력 파일 이나 /dev/null데이터를 제공하는 다른 파일을 사용할 수도 있습니다 . 이 명령은 출력 파일/장치의 시작 부분에서 데이터 쓰기를 시작합니다.

관련 정보