출력 파일이 / dev / null 일 때 tar가 파일 내용을 건너 뛰는 이유는 무엇입니까?


21

400 GiB 이상의 데이터가있는 디렉토리가 있습니다. 내가 생각하는 간단한 방법은이었다, 그래서 모든 파일이 오류없이 읽을 수 있는지 확인하고 싶었다 tar/dev/null. 그러나 대신 다음과 같은 동작이 나타납니다.

$ time tar cf /dev/null .

real    0m4.387s
user    0m3.462s
sys     0m0.185s
$ time tar cf - . > /dev/null

real    0m3.130s
user    0m3.091s
sys     0m0.035s
$ time tar cf - . | cat > /dev/null
^C

real    10m32.985s
user    0m1.942s
sys     0m33.764s

위의 세 번째 명령은 이미 오랫동안 실행 된 후 Ctrl+에 의해 강제로 중지되었습니다 C. 또한 처음 두 명령이 작동하는 동안 포함 된 저장 장치의 활동 표시기 .는 거의 항상 유휴 상태였습니다. 세 번째 명령으로 표시등이 계속 켜져있어 매우 바쁩니다.

따라서 tar출력 파일이임을 알 수있을 때 /dev/null, 즉 /dev/null파일 핸들을 tar쓰기 위해 직접 열면 파일 본문이 건너 뛴 것처럼 보입니다. ( v옵션을 추가 tar하면 디렉토리에있는 모든 파일이 tar'빨간색'으로 인쇄됩니다 .)

그래서 왜 이것이 그렇게 궁금합니까? 그것은 일종의 최적화입니까? 그렇다면 왜 tar그런 특별한 경우에 대해 모호한 최적화를 원할까요?

Linux 4.14.105 amd64에서 glibc 2.27과 함께 GNU tar 1.26을 사용하고 있습니다.


7
실용적인 대안으로 다음과 같은 것을 고려하십시오 find . -type f -exec shasum -a256 -b '{}' +. 그것은 않습니다뿐만 아니라 실제로 읽고 모든 데이터를 검사하지만 출력을 저장하는 경우, 당신은 파일의 내용이 변경되지 않았 음을 확인하기 위해 나중에 다시 실행할 수 있습니다.
Ilmari Karonen

일을 측정하기 위해 당신은 또한 사용할 수 있습니다 pv: tar -cf - | pv >/dev/null. 문제를 회피하고 진행 정보 (다양한 pv옵션)를 제공합니다
xenoid

GNU tar의 잘 알려진 미스 기능을 사용했습니다. gtar -cf /dev/zero ...원하는 것을 얻기 위해 사용하십시오 .
schily

답변:


25

그것은 이다 문서화 된 최적화 :

에 아카이브를 만들 때 /dev/nullGNU tar는 입력 및 출력 작업을 최소화하려고합니다. GNU tar와 함께 사용되는 Amanda 백업 시스템에는이 기능을 사용하는 초기 크기 조정 단계가 있습니다.


4
아, 이것은 내가 설치 한 매뉴얼 페이지에 설명되어 있지 않습니다. info tar대신 시도해보아야 할 것…
Ruslan

9
그들은 실제로 매뉴얼과 정보 페이지를 동기화 상태로 유지해야합니다. 실제로는 그렇지 않은 버그입니다.
Xen2050

9
@Ruslan 대부분의 GNU 유틸리티에서 매뉴얼 페이지는 간단한 요약 만 포함합니다. 기본적으로 무언가를 수행하는 옵션이 있지만 옵션의 이름을 기억하지 못하는 옵션을 기억할 때 충분합니다. 완전한 문서는 매뉴얼 페이지로 잘 변환되지 않는 형식으로 info되어 있으며 브라우저에서 또는 HTML로 사용 가능 합니다.
Gilles 'SO- 악마 중지'

18
그것은 A의 인식 문제 .
Owen

8

이것은 다양한 프로그램에서 발생할 수 있습니다 cp file /dev/null. 내 디스크 읽기 속도를 추정하는 대신 몇 밀리 초 후에 명령이 리턴되었습니다.

내가 기억하는 한, 그것은 Solaris 또는 AIX에 있었지만 원칙은 모든 종류의 유닉스 시스템에 적용됩니다.

옛날에는 프로그램이 파일을 어딘가에 복사 할 때 read디스크 (또는 파일 설명자가 참조하는 모든 것)에서 메모리로 데이터를 가져 오는 호출 (메모리가 read반환 될 때 모든 것이 보장됨 )과 write호출 사이에서 번갈아 나타납니다 (메모리 청크를 가져 와서 내용을 대상으로 보냅니다).

그러나 동일한 방법으로 달성 할 수있는 두 가지 새로운 방법이 있습니다.

  • Linux에는 시스템 호출 copy_file_range(다른 유닉스에 이식 가능하지 않음) 및 sendfile(휴대용; 원래 파일을 네트워크로 보내려고하지만 현재 모든 대상을 사용할 수 있음)이 있습니다. 전송을 최적화하기위한 것입니다. 프로그램이 그 중 하나를 사용하면 커널이 대상을 인식 /dev/null하고 시스템 호출을 no-op로 바꿉니다.

  • 프로그램은 mmap대신 파일 내용을 가져 오는 데 사용할 수 있습니다 read. 이는 기본적으로 "시스템 호출이 반환 될 때 데이터가 있는지 확인하십시오"대신 "메모리에 액세스하려고 할 때 데이터가 있는지 확인하십시오"를 의미합니다. 따라서 프로그램은 mmap소스 파일을 생성 한 다음 write매핑 된 메모리 청크 를 호출 할 수 있습니다 . 그러나 쓰기 /dev/null가 쓰여진 데이터에 액세스 할 필요가 없으므로 "있는지 확인"조건이 트리거되지 않으므로 파일을 읽을 수 없습니다.

gnu tar가 쓰기를 감지 할 때이 두 가지 메커니즘 중 어떤 메커니즘을 사용하는지 확실하지 /dev/null않지만, 읽기 속도를 검사하는 데 사용되는 프로그램 이 | cat > /dev/null대신 실행 되어야하는 > /dev/null이유입니다. | cat > /dev/null할 수 피할 다른 모든 경우에.


GNU tar정보 페이지 (다른 답변 참조)의 의미는 파일을 열지 않고 통계 파일 만 사용할 수있는 특수 모드가 있다는 것입니다. 사실 방금 tar cf /dev/null foo*몇 파일을 확인 했는데 예, newfstatat(..., AT_SYMLINK_NOFOLLOW)시스템 호출 만으로도 open()시간이 업데이트 되지 않을 수도 있습니다. 그러나 특별히 감지하지 않고도 발생할 수있는 메커니즘을 설명하는 +1입니다.
Peter Cordes

mmap 설명 이 " 기록 된 데이터에 액세스"대신 " 읽은 데이터에 액세스"로 표시되어야합니까 ?
Wayne Conrad

splice(2)Linux 에서도 참조하십시오 . 사실, 교체 cat > /dev/null와 함께 pv -q > /dev/null(이 사용 splice()가능성이 오버 헤드를 줄일 리눅스). 또는 dd bs=65536 skip=9999999999 2> /dev/null, 또는 wc -c > /dev/nulltail -c1 > /dev/null...
스테판 Chazelas가
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.