나는 최근에 우리가 사용할 수있는 실현 cat
만큼 dd
, 그리고 그건 사실보다 더 빨리dd
dd
성능이 아니라 블록 크기가 실제로 올바른 테이프를 처리하는 데 유용하다는 것을 알고 있습니다. 하지만 요즘에는 dd
무언가 cat
할 수없는 상황이 있습니까? (여기서는 성능 차이가 20 % 미만인 것으로 간주합니다.)
구체적인 예는 좋을 것입니다!
나는 최근에 우리가 사용할 수있는 실현 cat
만큼 dd
, 그리고 그건 사실보다 더 빨리dd
dd
성능이 아니라 블록 크기가 실제로 올바른 테이프를 처리하는 데 유용하다는 것을 알고 있습니다. 하지만 요즘에는 dd
무언가 cat
할 수없는 상황이 있습니까? (여기서는 성능 차이가 20 % 미만인 것으로 간주합니다.)
구체적인 예는 좋을 것입니다!
답변:
외관상으로 dd
는 IBM 운영 체제의 도구로 외래 모양 (매개 변수 전달)을 유지하는 도구로 거의 사용되지 않는 기능 (예 : EBCDIC에서 ASCII 로의 변환 또는 엔디안 반전 등)을 수행합니다.
내가 생각하는 데 사용 하는이 dd
빠른 (때문에 버퍼링을보다 효율적으로 사용) 같은 디스크에 대량의 데이터 블록을 복사하는이었다, 그러나 이것은 사실이 아니다 적어도 오늘날의 리눅스 시스템에서.
필자 dd
는 실제로 블록 단위로 읽기가 수행되는 테이프를 다룰 때 일부 옵션이 유용 하다고 생각 합니다 (테이프 드라이버는 디스크 드라이버처럼 저장 매체의 블록을 숨기지 않습니다). 그러나 나는 구체적인 내용을 모른다.
dd
다른 POSIX 도구로 (쉽게) 수행 할 수없는 한 가지 작업 은 스트림 의 첫 N 바이트 를 취하는 것 입니다. 많은 시스템에서이 기능을 수행 할 수 head -c 42
있지만 head -c
, 일반적으로 POSIX에는 없지만 OpenBSD에서는 현재 사용할 수 없습니다. ( tail -c
POSIX입니다.) 또한 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
거의 쓸모가 없습니다. 텍스트 (또는 이진 파일) 처리 도구로서 매우 유용합니다!
trunc
과 seek
에서 사용할 수있는이 dd
).
dd
stdio 버퍼링으로 인해 읽지 않은 데이터를 잠재적으로 파괴하지 않고도 검색 할 수없는 파일 디스크립터에서 이진 데이터를 읽을 수 있습니다. 예를 보려면 여기를 참조하십시오 : etalabs.net/sh_tricks.html
head -c N
전화를 read
결코 NetBSD의 5.1 N. 넘어 간다, head -c
호출합니다 getc
. FreeBSD 7.4에서는를 head -c
호출합니다 fread
.
dd
는 O_DIRECT 등을 쉘 스크립팅에 노출시킵니다.
이 dd
명령에는 cat이 수용 할 수없는 많은 옵션이 포함됩니다. 아마도 귀하의 사용 사례에서 고양이는 실행 가능한 대체물이지만 dd 대체물은 아닙니다.
한 가지 예는 dd
무언가의 일부는 복사하지만 전부는 복사하지 않는 데 사용 됩니다. 아마도 장치의 알려진 위치에 따라 하드 드라이브에서 iso 이미지의 중간 부분이나 파티션 테이블의 일부 비트를 제거하려고 할 수 있습니다. 으로 dd
당신이 시작을 지정할 수 있습니다 중지하고 이러한 작업을 가능 수량 옵션을 제공합니다.
이 옵션을 dd
사용하면 세밀한 데이터 조작에 반드시 필요한 반면 cat
*는 전체 파일 객체, 장치 또는 스트림에서만 작동 할 수 있습니다.
* Gilles의 의견에서 언급했듯이 cat
다른 도구와 결합 하여 무언가의 일부를 분리 할 수는 있지만 cat
여전히 전체 객체에서 작동합니다.
dd
실제로는 저수준 장치와 관련이 없으며 /dev
다른 장치 와 같은 항목이 필요합니다 . 로 전체 파티션을 복사 cat
하거나로 일부를 복사 할 수 있습니다 tail +c $(($start+1)) | head -c $count
.
cat | head | tail
마지막 몇 MB를 가져 오기 위해 1.6TB 디스크 이미지를 공급 하면 디스크 회전이 지구에 더 가까이 달을 빨아들입니다.
아무도 아직 작성 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
보고서에만 최대 크기는 파일로 성장할 수 있습니다.
ls -ls
희소 크기를 보여줍니다.
dd of=sparse-file bs=1 count=0 seek=10G
와 같습니다 truncate -s 10GB sparse-file
. 혼동 충분 truncate
하고 dd
정확한 반대 해석이 GB
대를 G
...
man dd
말한다 : MB =1000*1000, M =1024*1024
등등. 그리고 man truncate
말합니다 : MB 1000*1000, M 1024*1024
그렇기 때문에 아무런 차이 가 없습니다. GNU coreutils dd
와 truncate
GNU coreutils를 모두 사용합니다 . 당신도 그렇게해야합니다! :-)
하드 드라이브의 특정 부분을 다른 것으로 재정의하는 것이 일반적인 예입니다. 예를 들어 다음 명령을 사용하여 MBR을 삭제하려고 할 수 있습니다.
dd if=/dev/zero of=/dev/sda bs=446 count=1
또한 빈 파일을 만들 수 있습니다 (예 : 루프 디스크 이미지).
dd if=/dev/zero of=10mb.file bs=1024k count=10
몇 년 동안 내가 생각해 낸 dd 트릭은 다음과 같습니다.
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가 매우 유용하다는 것을 알았습니다. 그리고 이것은 제가 머리 꼭대기에서 생각할 수있는 세 가지 예일뿐입니다.
일부 출력 내용을 리디렉션 할 수 있습니다. 다음과 sudo
같이 작성해야 할 경우 특히 유용합니다 .
echo some_content | sudo dd status=none of=output.txt
게다가 sudo
다음과 같습니다.
echo some_content > output.txt
또는 이것 :
echo some_content | sudo tee output.txt > /dev/null