dd vs cat — dd는 요즘에도 여전히 관련이 있습니까? 크기가 실제로 올바른 테이프를

나는 최근에 우리가 사용할 수있는 실현 cat만큼 dd, 그리고 그건 사실보다 더 빨리dd

dd성능이 아니라 블록 크기가 실제로 올바른 테이프를 처리하는 데 유용하다는 것을 알고 있습니다. 하지만 요즘에는 dd무언가 cat할 수없는 상황이 있습니까? (여기서는 성능 차이가 20 % 미만인 것으로 간주합니다.)

구체적인 예는 좋을 것입니다!



답변

외관상으로 dd는 IBM 운영 체제의 도구로 외래 모양 (매개 변수 전달)을 유지하는 도구로 거의 사용되지 않는 기능 (예 : EBCDIC에서 ASCII 로의 변환 또는 엔디안 반전 등)을 수행합니다.

내가 생각하는 데 사용 하는이 dd빠른 (때문에 버퍼링을보다 효율적으로 사용) 같은 디스크에 대량의 데이터 블록을 복사하는이었다, 그러나 이것은 사실이 아니다 적어도 오늘날의 리눅스 시스템에서.

필자 dd는 실제로 블록 단위로 읽기가 수행되는 테이프를 다룰 때 일부 옵션이 유용 하다고 생각 합니다 (테이프 드라이버는 디스크 드라이버처럼 저장 매체의 블록을 숨기지 않습니다). 그러나 나는 구체적인 내용을 모른다.

dd다른 POSIX 도구로 (쉽게) 수행 할 수없는 한 가지 작업 은 스트림 의 첫 N 바이트취하는 것 입니다. 많은 시스템에서이 기능을 수행 할 수 head -c 42있지만 head -c, 일반적으로 POSIX에는 없지만 OpenBSD에서는 현재 사용할 수 없습니다. ( tail -cPOSIX입니다.) 또한 head -c존재하는 경우에도 소스에서 너무 많은 바이트를 읽을 수 있습니다 (내부에서는 stdio 버퍼링을 사용하기 때문에). 읽기만하는 특수 파일에서 읽는 경우 문제가됩니다. (현재 GNU coreutils는로 정확한 개수를 읽지 head -c만 FreeBSD와 NetBSD는 stdio를 사용합니다.)

더 일반적으로, dd유닉스 도구 사이에 고유 한 기본 파일 API에 대한 인터페이스를 제공합니다에만 dd할 수 덮어 쓰거나 잘라 파일을 언제든지 또는 추구 파일에. (이것은 dd고유 한 능력이며 큰 기능입니다. 이상하게도 dd다른 도구가 할 수있는 것으로 잘 알려져 있습니다.)

  • 대부분의 유닉스 도구는 출력 파일을 덮어 씁니다. 즉, 내용을 지우고 처음부터 다시 시작합니다. 이것은 >쉘에서도 리디렉션 을 사용할 때 발생 합니다.
  • >>쉘에서 경로 재 지정 또는 을 사용하여 파일 내용에 추가 할 수 있습니다 tee -a.
  • 특정 지점 이후에 모든 데이터를 제거하여 파일을 줄이려 면 truncate함수를 통해 기본 커널 및 C API에서 지원 하지만 다음을 제외한dd 모든 명령 줄 도구에는 노출되지 않습니다 .

    dd if=/dev/null of=/file/to/truncate seek=1 bs=123456  # truncate file to 123456 bytes
    
  • 파일 중간에 데이터를 덮어 쓰려면 다시 잘라 내지 않고 파일을 열어 ( lseek필요한 경우 원하는 위치로 이동하도록 호출) 파일을 열어 언더 실링 API에서이 작업을 수행 dd할 수 있습니다. 절단 또는 추가하거나, 시크 쉘 (부터 보다 복잡한 예 ).

    # zero out the second kB block in the file (i.e. bytes 1024 to 2047)
    dd if=/dev/zero of=/path/to/file bs=1024 seek=1 count=1 conv=notrunc
    

그래서… 시스템 도구로서 dd거의 쓸모가 없습니다. 텍스트 (또는 이진 파일) 처리 도구로서 매우 유용합니다!


답변

dd명령에는 cat이 수용 할 수없는 많은 옵션이 포함됩니다. 아마도 귀하의 사용 사례에서 고양이는 실행 가능한 대체물이지만 dd 대체물은 아닙니다.

한 가지 예는 dd무언가의 일부는 복사하지만 전부는 복사하지 않는 데 사용 됩니다. 아마도 장치의 알려진 위치에 따라 하드 드라이브에서 iso 이미지의 중간 부분이나 파티션 테이블의 일부 비트를 제거하려고 할 수 있습니다. 으로 dd당신이 시작을 지정할 수 있습니다 중지하고 이러한 작업을 가능 수량 옵션을 제공합니다.

이 옵션을 dd사용하면 세밀한 데이터 조작에 반드시 필요한 반면 cat*는 전체 파일 객체, 장치 또는 스트림에서만 작동 할 수 있습니다.

* Gilles의 의견에서 언급했듯이 cat다른 도구와 결합 하여 무언가의 일부를 분리 할 수는 있지만 cat여전히 전체 객체에서 작동합니다.


답변

아무도 아직 작성 DD를 사용할 수있는 언급하지 않았다 스파 스 파일을 하지만, truncate같은 목적을 위해 이용 될 수있다.

dd if=/dev/zero of=sparse-file bs=1 count=1 seek=10GB

이것은 거의 즉각적이며 예를 들어 루프백 파일로 사용할 수있는 임의의 큰 파일을 만듭니다.

loop=`losetup --show -f sparse-file`
mkfs.ext4 $loop
mkdir myloop
mount $loop myloop

좋은 점은 처음에는 하나의 디스크 공간 블록 만 사용하고 나서 필요한만큼만 증가한다는 것입니다 (10GB 파일의 4 번째 형식은 시스템에서 291MB를 소비 함). 사용 du– 실제로 사용되는 디스크 공간을 보려면 ls보고서에만 최대 크기는 파일로 성장할 수 있습니다.


답변

하드 드라이브의 특정 부분을 다른 것으로 재정의하는 것이 일반적인 예입니다. 예를 들어 다음 명령을 사용하여 MBR을 삭제하려고 할 수 있습니다.

dd if=/dev/zero of=/dev/sda bs=446 count=1

또한 빈 파일을 만들 수 있습니다 (예 : 루프 디스크 이미지).

dd if=/dev/zero of=10mb.file bs=1024k count=10


답변

dd하드 드라이브 또는 다른 저장 장치의 부팅 섹터를 백업 dd if=/dev/sda of=boot_sector.bin bs=512 count=1한 다음 나중에 다시 쓰는 데 매우 유용 합니다 ( dd if=boot_sector.bin of=/dev/sda). 암호화 된 볼륨의 헤더를 백업 할 때도 유용합니다.

cat그렇게 할 수는 있지만 재 작성 부분에서는 그것을 믿지 않을 것입니다. cat특정 바이트 수만 읽고 쓰기 가 어렵습니다 .


답변

필자는 최근 리눅스 역사상 처음으로 몇 백 GB 용량의 파티션을 복제해야하는 원인이 있었다 (참고로 cp -ar또는 rsync여러 번 나에게 도움이 되었음 ). 물론 나는 dd‘모든 사람들이 그것이 당신이 사용하는 것을 알고 있음을 알고 있습니다. 약간의 인터넷 검색으로 인해 나를 ddrescue몇 번이나 사용했으며 훌륭하게 잘 작동했습니다 (dd보다 훨씬 빠름).


답변

몇 년 동안 내가 생각해 낸 dd 트릭은 다음과 같습니다.

비 친화적 인 tty 또는 비 대화식 모드 bash에서 잘라 내기 및 붙여 넣기

EOF / ^ D / ^ F가 감지되지 않는 경우 dd를 사용하여 텍스트 파일을 호스트로 전송할 수 있습니다. 지정된 양의 바이트 후에 자동으로 읽기를 중지하기 때문입니다.

나는 작년에 원격 호스트에서 tty가 아닌 쉘을 얻을 수 있고 파일을 전송 해야하는 보안 연습 중에 최근에 이것을 사용했습니다.

사실, 나는 바이너리 파일을 base64로 인코딩하고 느리지 만 안정적인 pure-bash base64 디코딩 스크립트를 사용하여 바이너리 파일을 만들었습니다.

dd of=textfile.txt bs=1 count=<size_of_data_in_paste_buffer>

매우 멋진 트릭은 dd가 실행되는 동안 USR1 신호를 보내면 현재 상태 (바이트 읽기, 초당 바이트)를 방출한다는 것입니다.

범용 처리량 상태 필터

나는 stdout을 통해 데이터를 내보내는 모든 프로그램에 대한 순수한 bash 진행 필터로 작동하도록 이것을 썼습니다. (참고 : 거의 모든 것은 stdout을 통해 데이터를 방출합니다. 바이트 수, 인쇄 해시 표시 (해시 모드가 설정된 경우 올드 스쿨 FTP 등)

(주) 진행 파일은 절름발이입니다. 이것은 대부분 개념 증명입니다. 다시 수정하면 변수를 사용합니다.

 dd bs=$BLKSZ of=${TMPFILE} 2>&1 \
                | grep --line-buffered -E '[[:digit:]]* bytes' \
                | awk '{ print $1 }' >> ${PROGRESS} &

 while [[ $(pidof dd) -gt 1 ]]; do

        # PROTIP: You can sleep partial seconds
        sleep .5

        # Force dd to update us on it's progress (which gets
        # redirected to $PROGRESS file.
        pkill -USR1 dd
        local BYTES_THIS_CYCLE=$(tail -1 $PROGRESS)
        local XFER_BLKS=$(((BYTES_THIS_CYCLE-BYTES_LAST_CYCLE)/BLKSZ))

        if [ $XFER_BLKS -gt 0 ]; then
                printf "#%0.s" $(seq 0 $XFER_BLKS)
                BYTES_LAST_CYCLE=$BYTES_THIS_CYCLE
        fi
done

익명 쉘 파일 핸들을 사용하는 슬라이스 앤 다이스 파일

다음은 tmp 파일을 사용하여 부분 파일 데이터를 저장하지 않고 익명의 파일 핸들을 통해 tar 입력을 제공하여 오류없이 추출 할 수있는 서명 된 tar 파일을 얻는 방법에 대한 의사 코드 예입니다.

generate_hash() {
    echo "yay!"
}

# Create a tar file, generate a hash, append it to the end
tar -cf log.tar /var/log/* 2>/dev/null
TARFILE_SIZE=$(stat -f "%z" log.tar)
SIGNATURE=$(generate_hash log.tar)
echo $SIGNATURE >>log.tar

# Then, later, extract without getting an error..

tar xvf <(dd if=$OLDPWD/log.tar bs=1 count=${TARFILE_SIZE})

tl; dr는 : dd가 매우 유용하다는 것을 알았습니다. 그리고 이것은 제가 머리 꼭대기에서 생각할 수있는 세 가지 예일뿐입니다.