[unix] 압축을 풀지 않고 tar 아카이브로 파일보기

tarred 파일의 내용을 추출하지 않고 내용을 보려고합니다. 시나리오 : a.tar가 있고 그 안에 파일이 ./x/y.txt있습니다. y.txt실제로를 추출하지 않고 의 내용을보고 싶습니다 a.tar.



답변

그것은 아마 GNU의 특정 옵션,하지만 당신은 사용할 수 -O또는 --to-stdout표준 출력에 추출물에 파일을

$ tar -axf file.tgz foo/bar -O


답변

./x/y.txt의 내용을 a.tar에서 STDOUT으로 인쇄합니다.

tar xfO a.tar ./x/y.txt


답변

이것은 간단합니다

less  a.tar:./x/y.txt

이 마술의 트릭은 당신이 경우 작동 lesspipe설치되어있는 경우는 ENV 변수 LESSOPEN로 정의된다 | /usr/bin/lesspipe.sh %s당신이있는 경우에 예상되는 lesspipe가 제대로 설치.


답변

아, 그러나 이것은 파일 내의 파일 내용에 관한 질문 tar입니다. 실제로 어떤 경우에는 그렇게 어렵지 않습니다. 문제는 tar파일이 차단 된 스트림 파일 일뿐입니다. 아카이브 내의 각 파일은 그 이전의 파일 이후에 발견되며 각 파일은 지정된 형식 에 따라 메타 데이터 헤더 를 가져옵니다 .

이 형식을 기반으로 한 번 작성했습니다 shitar. 이것은 몇 줄의 dd셸 스크립트 tar였으며 즉시 블록 장치 스트림 을 만들 수있었습니다 . 동일하게, 더 최근에는 다음 과 같은 몇 줄의 코드를 작성했습니다 .

tar --no-recursion -c ./      |
{ printf \\0; tr -s \\0; }    |
cut -d '' -f-2,13             |
tr '\0\n' '\n\t'

tar파일을 즉시 분리 하고 구성 요소 텍스트 파일에서 인라인 변환을 수행합니다. 이 cut필드 는 NUL로 구분 된 입력 라인 의 필드 1,2,13 을 가리 킵니다 . 512 바이트마다 한 번씩 발생할 수있는 레코드 구분 기호 를 단 하나의 NUL로 압축하고 제거 할 수 있기 때문에 파일에 텍스트 파일 만 포함되어 있으면 이러한 작업이 쉬워 집니다.tartar

tar헤더 형식은 다음과 같습니다.

field    offset   len
name     0        100
mode     100      8
uid      108      8
gid      116      8
size     124      12
mtime    136      12
chksum   148      8
typeflag 156      1
linkname 157      100
magic    257      6
version  263      2
uname    265      32
gname    297      32
devmajor 329      8
devminor 337      8
prefix   345      155

tar아카이브 형식의 훨씬 더 복잡한 측면으로 간단한 조작 을 처리하는 상대적 용이성 사이에 급격한 기울기가 있음을 이해 하십시오. 작은 유형의 파일을 함께 묶거나 예측할 수있는 유형의 멤버 만 포함 된 아카이브를 분할하는 것과 같은 간단한 작업은 몇 개의 쉘 파이프로 쉽게 수행 할 수 있지만 임의의 아카이브 멤버를 안정적으로 처리하는 것은 쉬운 일이 아닙니다.

이러한 멤버가 임의의 이진 데이터를 포함하는 경우 특히 어렵습니다. 신뢰할 수있는 응용 프로그램을 확실히 배제 할 수 있습니다. tr -s이 어려움은 기본 및 / 또는 문자 세트 이외 의 다양한 유형의 파일이 네이티브 및 / 또는 문자 세트 이외의 파일을 사용하는 경우에만 복잡 합니다. 원본 보관 파일은 처리 할 준비가되지 않은 형식 응용 프로그램 특이성을 사용하여 구현되었습니다. 그리고 이것은 tar아카이브 유형 의 기본적이고 표준화 된 측면에 대해서만 다루고 있습니다. 확장 헤더 추가 및 확장명 확장 및 스파 스 파일 및 압축 및 … 음, 행운을 빕니다.

기본으로 돌아가서 아카이브 의 표준 레코드 크기 tar는 20 블록 또는 10240 바이트입니다. 그러나 표준 레코드 크기로 차단되고 표준 파일 형식과 표준 ustar헤더 만 포함 된 아카이브를 고려할 때 size헤더 필드 에 따라 읽기를 수행하여 멤버 헤더와 멤버 헤더 간을 건너 뛰어야 합니다. 당신이 찾는. 거기에 size도달하면 대상 멤버 헤더의 꼬리에서 시작하여 오프셋 에서 바이트 단위로 읽습니다 . 그리고 그것은 당신의 파일입니다.

그러나 헤더를 건너 뛰기는 쉽지 않습니다. 다른 유형은에 해당하는 실제 데이터 블록이 추가되거나 추가되지 않습니다 size. 예를 들어, 디렉토리 및 링크에는 이러한 데이터 블록이없고 헤더 설명 만 포함되므로 size필드를 건너 뛰기 수식에 적용해야하는지 여부를 정확하게 확인하기 전에 현재 헤더의 파일 유형을 확인할 준비가되어 있어야합니다 .

또한 아카이브 멤버의 크기가 10240 표준 레코드 크기 와 잘 동기화되는지 여부에 따라 레코드 크기 요소 에 각각 0 블록이 추가되거나 추가되지 않을 수 있습니다. 그리고 레코드 크기는 아카이브 생성시 선언 될 수 있으므로 20 블록이 될 수는 없지만 사양에 따라 항상 512 바이트 단위로 차단되어야합니다.

  • 우스타
    • tar교환 형식; 확장 설명 섹션을 참조하십시오 . 문자 특수 아카이브 파일에 대한이 형식 의 기본 블록 크기10240 입니다. 구현 은 512의 배수 인 32256 보다 작거나 같은 모든 블록 크기 값을 지원해야합니다 .

따라서 tar임의의 이진 데이터를 포함 할 수있는 파일을 포함 할 수있는 파일 로 작업하는 경우 파일 형식에 따라 알고리즘을 통해 파일을 건너 뛰어야합니다. 사양은 말합니다 :

  • size필드는 옥텟에서 파일의 크기입니다.
    • 경우] typeflag필드 형으로 파일에 설정되어 1 (a 링크 ) 또는 2 (a 심볼릭 링크 )size필드는 0으로 지정된다.
    • 는 IF typeflag필드 형식의 파일을 지정하는 설정 5 ( 디렉토리 )size해당 레코드 유형의 정의에 설명 된대로 필드 해석된다.
    • 유형 1 , 2 또는 5 에 대한 데이터 논리 레코드는 저장되지 않습니다 .
    • 경우] typeflag필드에 설정된 3 ( 문자 특별 파일) , 4 ( 특수 블록 파일) 또는 (6) ( FIFO가 ) 상기의 의미 size필드는 POSIX.1-2008의 부피로 지정하고, 데이터가 논리 레코드 수 없다 매체에 저장됩니다.
    • 또한, 유형 6size읽을 때 필드는 무시해야한다.
  • typeflag필드가 다른 값으로 설정 되면, 나눗셈 결과의 일부를 무시하고 헤더 다음에 기록 된 논리 레코드의 수는 입니다.( (size+ 511 ) / 512 )

… 물론 각 헤더의 개별 크기도 고려합니다. 이는 회원 당 추가 블록입니다. 따라서 원하는 헤더와 일치하는 헤더에 도달 할 때까지 헤더에서 헤더로 읽기를 건너 뛸 수 있습니다. 그러면 현재 레코드가 단순히 파일 또는 실제 파일에 대한 링크 를 설명하는지 여부를 확인해야 합니다 . 동일한 파일이 여러 번 아카이브에 추가 될 때 실제 파일의 데이터가 아카이브의 다른 곳에서 이미 발견 될 수 있기 때문에 많은 파일에 링크 헤더 tar만 포함 되기 때문에 이는 특히 중요 합니다.

chksum필드에 계산을 적용 하고 원하는 파일이 실제로 원하는 파일인지 확인해야합니다. tar의는 chksum매우 간단 though-입니다 :

  • cksum
    • chksum헤더 논리 레코드의 모든 옥텟의 단순 합계 8 진수 값 1991 표준 IRV 표현 : 필드는 ISO / IEC 646이어야한다. 헤더의 각 옥텟은 부호없는 값으로 취급됩니다. 이 값은 부호없는 정수에 추가되고 0으로 초기화되며 정밀도는 17 비트 이상이어야합니다. 체크섬을 계산할 때 chksum필드는 모두 <space> 문자 인 것처럼 처리됩니다 .

물론 실제로 그렇게 할 필요 가 없습니다. tar이미 할 수 있는 일이기 때문입니다. 따라서 아카이브를 검색하고 파일을 추출하는 데 사용해야합니다. 그렇게하면 자신이 무엇을하고 있는지 아는 경우와는 다른 방식으로 일을하지 않을 것입니다. 단, 그것이 직업이기 때문에 더 빠르고 더 잘할 것입니다. 어쨌든 왜해야합니까?


답변

이 라인을 사용할 수 있습니다

tar -axf a.tar -O


답변