리눅스 타르 -T-즉시 작동하지 않습니다


3

Linux gnu tar에 문제가 있습니다. 옵션을 사용하는 경우

-T -  (for file list from stdin) or
-T named_pipe_file    ,

이것은 즉시 작동하지 않습니다. 예를 들어, 간단한 대화식 스크립트 :

while read x; do echo $x; done|\
tar cvf tar.tar -T -

tar는 입력 EOF를 표시하기 위해 ^ D를 누를 ​​때만 아카이브를 시작합니다.

mkfifo named_pipe
tar cvf tar.tar -T named_pipe
while read x; do echo $x; done >named_pipe

tar가 버퍼링을하는 것 같습니다. 그러나 얼마나 걸립니까? 많은 파일을 TAR로 다시 압축해야하지만 디스크 공간이 거의 없습니다. 그런 다음 즉석에서이 작업을 수행해야합니다. tar 옵션 --remove-files를 사용해야합니다. 그러나 -T 옵션에 대한 상호 작용이 없으면 impossobie입니다. 계획에서 코드의 "while"부분은 파일을 파일로 순차적으로 압축 해제하고 제거를 위해 TAR 및 다음 파일을 대기해야합니다. 아이디어 주셔서 감사합니다 :)

내 타르 버전 : tar (GNU tar) 1.26 (C) 2011 FSF


당신은 먹이 tar파일 이름 또는 압축해야 실제 데이터를? 이 -T옵션은 파일 이름 목록을 요구하며 시스템의 루프에 광고 된대로 작동합니다.
— terdon

답변:


3

tar 기존 아카이브에 추가 할 수 있으므로 다음을 수행 할 수 있습니다.

touch tarfile.tar
command_that_produces_file_list | xargs tar rf tarfile.tar

불행히도, 이것은 즉시 압축에서 작동하지 않습니다. 운 좋게도 tar형식은 간단해서 해킹을 할 수 있습니다.

command_that_produces_file_list | {
  xargs -i sh -c 'tar c {} | head -c $(( (`stat --printf="%s" {}` + 511) / 512 * 512 + 512))';
  dd if=/dev/zero bs=512 count=2 2>/dev/null;
} | compression_utility

tar출력은 각 파일에 대해 512 바이트 헤더와 파일 데이터를 보유하기에 충분한 512 바이트 블록으로 구성됩니다. 그런 다음 2 512 바이트 이상의 0 블록을 추가합니다. 이 코드는 tar의 출력을 캡처하고 여분의 0 블록을 제거하고 여러 호출의 출력을 결합한 tar다음 종료 0 블록을 고수합니다. 출력은 파이프를 통해 압축 유틸리티로 전송되며 압축 유틸리티는 tars 와 동시에 실행됩니다 .


나는 이것에 대해 알고 있습니다. 압축되지 않은 아카이브 나 소프트웨어에 노출되지 않은 하드 바어 압축 테이프의 경우에만 가능합니다. 해당 테이프는 소프트웨어에 압축되지 않은 것으로 표시됩니다. 나는 가능한 한 간단한 예를 만들었다. 스크립트에서는 tar에 대해 플래그 -9ev 및 --remove-files와 함께 xz 압축을 사용하고 있습니다.
— Znik

파일을 압축하고 일반 타르에 저장하면 tar를 사용하지 않는 솔루션을 찾을 수 있습니다. 이를 위해 무엇을해야합니까?
— wingedsubmariner

@ user215501 tar로이 작업을 수행하는 방법이 있습니다. 새로 편집 한 답변을 참조하십시오.
— wingedsubmariner 2018 년

@ingedsubmariner 및 (at) user215501 tar hack 형식으로 매우 멋진 업데이트 :) tar 의이 버그 (제 의견으로는)가 곧 제거되기를 바랍니다. 우리 중
— 누가이

@wingedsubmariner 모자가 당신에게 떨어져 있습니다, 선생님! :)
— Ярослав Рахматуллин

2

좋은 소식. 내 버그 리포트에 대한 답변을 bug-tar@gnu.org로 보내주십시오 :

보낸 사람 : Sergey Poznyakoff 날짜 :
2013 년 9 월 5 일 목요일 08:40:40 +0300 제목 : Re : [버그 타르] gnu tar, stdin 또는 명명 된 파이프의 옵션 -T는 대화식이 아닙니다.

안녕 그제 고르 츠,

이것은 커밋 1fe0c83d에서 시작하여 git HEAD에서 수정되었습니다.

감사합니다, Sergey

그런 다음이 리눅스 배포판에서 수정 될 때까지 기다리고 있습니다 :)


0

이 설명을 읽으십시오 (첫 번째 대답) : 파이프 명령은 어떤 순서로 실행됩니까?

입력 목록이 처리를 시작하기 전에 완료하기위한 tar 차단입니다. 논란의 여지없이 입력과 병렬로 처리하는 것이 유용 할 수는 있지만 GNU Tar이이를 지원한다고 생각하지 않습니다.

"--append 및 --remove-files" 를 처리하는 방법 과 같은 명령 줄 인수를 처리하는 "내부 프로 시저"에서 복잡성을 피하기 위해 전체 목록을 기다리는 것이 단지 추측 할 수 있습니다 . 나는 대부분의 사람들이 아카이브가 완료된 후 모든 파일을 대량으로 제거하는 것을 선호한다고 생각합니다 .이 경우에는 바람직하지 않습니다.

GNU 사람들은 대개 매우 친숙합니다. 왜 이것이 기능이 아닌지, 다른 도구로 어떻게 할 수 있는지, 나중에 Tar의 일부가되도록 요청할 수도 있습니다.

https://lists.gnu.org/mailman/listinfo/help-tar


불행히도 그것은 대답이 아닙니다. | sed 's / aa / bb /'명령 또는 명명 된 파이프 sed 's / aa / bb /'<named_pipe (확인)의 경우 "tar"부분을 예제에서 바꿀 수 있습니다. 이것은 완벽하게 작동합니다. 키보드 문자열을 입력하면 'aa'문구가 발견되면 즉시 바뀌고 화면으로 다시 인쇄됩니다. 파이프로 모든 것이 맞습니다. tar 명령이 주요 문제입니다.
— Znik

그것이 내가 말한 것이며, user215501은 결과적으로 행복한 소식으로 내 제안을 따랐습니다.;)
— Ярослав Рахматуллин

GNU 사람들은 정말 친절합니다 :) 그러나 tar에 관해서. 소스 파일을 즉시 제거 할 수 있습니다. 이것은 사람에 의해 결정된 임시 여유 공간을 절약하기 위해 수행됩니다. 다른 측면에서 tar 아카이브의 파일은 -T-옵션에 대해 STDIN에서 제공 한 것과 동일한 순서를 갖습니다. 실제로 tar는 버퍼링을 제거합니다. 현재 아카이브 / 완료된 파일이 아니라 이전 파일을 삭제합니다. 이것은 항상이 작업이 아니라 데이터 손실을 방지하는 것입니다. 높은 버퍼링과 높은 사전으로 강력한 압축 알고리즘을 사용하면 파일에 데이터가 저장되지 않지만 여전히 메모리에 유지됩니다.
— Znik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.