하나의 명령으로 여러 tar 파일을 연결합니다.

하나의 명령으로 여러 tar 파일을 연결합니다.

저는 매일 4~100개의 매우 큰 tar(~20GB) 아카이브 파일을 받습니다. 나는 과거에 파일 시스템에 있는 각 아카이브를 반복하면서 다음과 같은 작업을 수행하여 이들을 연결해 왔습니다.

/bin/tar -concatenate --file=allTars.tar receivedTar.tar

allTars.tar그러나 이것의 문제는 점점 더 많은 tar 파일을 연결함에 따라 다시 연결을 시작하려면 끝까지 읽어야 한다는 것입니다 . 다른 tar 파일을 추가하는 데 20분 이상이 걸리는 경우도 있습니다. 속도가 너무 느리고 합의된 전체 배송 시간이 누락되었습니다 allTars.tar.

또한 tar 명령에 다음과 같은 파일 목록을 전달해 보았습니다.

/bin/tar --concatenate --file=alltars.tar receiverTar1.tar receivedTar2.tar receivedTar3.tar...etc

이것은 매우 이상한 결과를 가져왔습니다. allTars.tar예상된 크기(즉, 모든 receivedTar.tar파일을 합친 크기에 가깝지만) allTars.tar압축을 풀 때 파일을 덮어쓰는 것처럼 보였습니다.

하나의 명령으로 이러한 모든 tar 파일을 연결하는 방법이 있습니까? 아니면 매번 연결되는 아카이브의 끝까지 읽을 필요가 없습니다.그리고모든 파일/데이터와 함께 올바르게 압축을 풀도록 합니까?

답변1

-i이는 도움이 되지 않을 수 있지만 최종 아카이브에서 추출할 때 옵션을 사용하려는 경우 간단히 cattar를 함께 사용할 수 있습니다. tar 파일은 레코드가 끝날 때까지 널로 가득 찬 헤더와 더 많은 널 패딩으로 끝납니다. tar를 사용하면 --concatenate덮어쓰기를 시작하기 위해 최종 헤더의 정확한 위치를 찾기 위해 모든 헤더를 통과해야 합니다.

tar 만 있으면 cat헤더 사이에 추가 null이 있습니다. 이 -i옵션은 tar에게 헤더 사이의 이러한 null을 무시하도록 요청합니다. 그래서 당신은 할 수 있습니다

cat  receiverTar1.tar receivedTar2.tar ... >>alltars.tar
tar -itvf alltars.tar

또한 귀하의 tar --concatenate모범이 효과가 있어야 합니다. 그러나 여러 tar 아카이브에 동일한 이름의 파일이 있는 경우 결과 tar에서 모두 추출할 때 해당 파일을 여러 번 다시 작성하게 됩니다.

답변2

이 질문은 다소 오래되었지만 다음 정보를 더 빨리 찾는 것이 더 쉬웠 으면 좋았을 것입니다. 따라서 다른 사람이 이 문제를 발견했다면 다음을 즐겨보세요.

위에서 Jeff가 설명한 내용은 gnu tar의 알려진 버그입니다(2008년 8월에 보고됨). 첫 번째 아카이브(옵션 다음 아카이브 -f)만 EOF 표시를 제거합니다. 2개 이상의 아카이브를 연결하려고 하면 마지막 아카이브가 파일 끝 표시 뒤에 "숨겨집니다".

tar의 버그입니다. 후행 0 블록을 포함하여 전체 아카이브를 연결하므로 기본적으로 결과 아카이브 읽기는 첫 번째 연결 후에 중지됩니다.

원천:https://lists.gnu.org/archive/html/bug-tar/2008-08/msg00002.html (및 다음 메시지)

버그의 나이를 고려하면 수정될 수 있을지 궁금합니다. 영향을 받는 임계 질량이 있는지 의심됩니다.

이 버그를 피하는 가장 좋은 방법은 -i적어도 파일 시스템의 .tar 파일에 대해 옵션을 사용하는 것입니다.

Jeff가 지적했듯이 tar --concatenate다음 아카이브를 연결하기 전에 EOF에 도달하는 데 오랜 시간이 걸릴 수 있습니다. 따라서 압축 해제 옵션이 필요한 "깨진" 아카이브에 갇히게 될 경우 tar -i다음을 제안합니다.

사용하는 대신 tar --concatenate -f archive1.tar archive2.tar archive3.tar 당신은 달리는 것이 더 나을 것 같습니다 cat archive2.tar archive3.tar >> archive1.tar또는 dd테이프 장치에 쓰려는 경우 파이프로 연결합니다. 또한 이것을 참고하세요~할 수 있었다새 데이터를 테이프에 쓰기(덮어쓰기) 전에 테이프를 제로화하지 않으면 예상치 못한 동작이 발생할 수 있습니다. 이러한 이유로 내 응용 프로그램에서 내가 취할 접근 방식은 질문 아래 설명에서 제안한 대로 중첩된 tar입니다.

위의 제안은 다음과 같은 매우 작은 샘플 벤치마크를 기반으로 합니다.

time tar --concatenate -vf buffer.100025.tar buffer.100026.tar
  real  65m33.524s
  user  0m7.324s
  sys   2m50.399s

time cat buffer.100027.tar >> buffer.100028.tar
  real  46m34.101s
  user  0m0.853s
  sys   1m46.133s

buffer.*.tar 파일의 크기는 모두 100GB이며, 각 호출을 제외하면 시스템은 거의 유휴 상태였습니다. 시간차는 작은 표본 크기에도 불구하고 개인적으로 이 벤치마크가 유효하다고 생각할 만큼 충분히 중요합니다. 그러나 이에 대한 판단은 여러분의 자유이며 아마도 자신의 하드웨어에서 이와 같은 벤치마크를 실행하는 것이 가장 좋습니다.

답변3

언급한 대로 두 번째 소스 아카이브가 추가되기 전에 대상 아카이브 파일을 끝까지 읽어야 합니다. GNU tar에는 -n파일을 검색할 수 있다고 가정하도록 지시하는 옵션이 있습니다(tar는 검색할 수 없는 테이프 및 스트림 아카이브용으로 설계되었음을 기억하세요). GNU tar는 기본적으로 파일을 검색할 수 있는지 자동 감지하지만, 여러분과 같은 많은 사용자는 옵션을 추가하여 tar가 각 레코드의 전체 내용 읽기를 건너뛰도록 할 수 있습니다 -n:

tar -n --concatenate --file=target_file.tar  other_file.tar

(작성 당시) tar 버전이 이 명령에 대해 예상대로 수행되는지 확인할 수 없습니다. 다른 사용자가 이 솔루션을 입증할 수 있는 능력이 있는 경우 아래에 의견을 남겨 주시면 이에 따라 이 답변을 업데이트하겠습니다.

답변4

연결에는 I/O 집약적이므로 RAID 0에 SSD 3개(1TB)가 필요한 것이 좋습니다. SATA 3의 단일 SSD는 500mb/s 읽기 및 쓰기 속도와 유사합니다. 비싸죠. 하지만 빠릅니다. x3.

관련 정보