리눅스 타르 -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.