tar 아카이브 내부의 디렉토리 이름 바꾸기


14

tar 아카이브 내부의 디렉토리 이름을 바꿀 수 있습니까? 내 유스 케이스는 특정 디렉토리 구조의 tarball을 가정하는 외부 제공 RPM 스펙 파일을 가지고 있으며 최상위 디렉토리 이름이 스펙 파일이 예상하는 것과 일치하지 않는 외부 제공 tarball을 가지고 있다는 것입니다. tarball 또는 RPM 사양 파일을 생성하는 스크립트를 제어하지 않으므로 다른 파일과 일치하도록 변경할 수 없습니다.

내가하고있는 일은 untarring, 디렉토리 이름 변경, 그리고 새로운 tarball을 만드는 것이지만, 다른 대안이 있는지 궁금합니다.


3
불행히도 나는 그것을 의심하지만 다른 사람이 방법이 있는지 알고 싶습니다. 가장 좋은 방법은 스크립트를 작성하여 untar, 이름 바꾸기 및 re-tar를하는 것입니다.
Kevin

답변:


8

적어도 파일 이름이 고정 크기 (100 바이트) 필드에 저장되는 구식 형식과 호환되는 아카이브의 경우 매우 어려워서는 안되지만 이름을 바꿀 수있는 도구는 알 수 없습니다. tar 아카이브에 파일을 넣습니다. 또한 압축 된 아카이브를 사용하면 새 파일을 만들어야합니다.

훨씬 쉬워야하지만 아카이브를 필터링하고 파일 이름을 바꿀 수있는 기존 도구는 알지 못합니다. 스크립트 언어로 tar 라이브러리 위에 하나를 작성할 수 있습니다. 예를 들어, Perl과 함께Archive::Tar tar 아카이브의 디렉토리 이름을 바꾸는 개념 증명 스크립트 있습니다. 아카이브는 완전히 메모리에로드됩니다. 이것은의 본질적인 한계입니다 Archive::Tar.

#!/usr/bin/env perl
## Usage: tar-rename OLDPREFIX NEWPREFIX
use strict;
use warnings;
use Archive::Tar;
my ($from, $to) = @ARGV;
my $tar = Archive::Tar->new(\*STDIN);
foreach my $file ($tar->get_files()) {
    my $name = $file->name;
    $name =~ s~\A\Q$from\E($|/)~$to$1~;
    $file->rename($name) unless $name eq $file->name;
}
$tar->write(\*STDOUT);

GNU tar는 즉석에서 멤버의 이름을 바꾸는 기능이 없지만 pax(POSIX 대신 cpiotar)는 그렇게합니다. 그러나 pax아카이브에서 읽고 쓸 수는 없습니다 . AVFS를 통해 아카이브를 일반 트리로 표시 하고을 사용하여 새 아카이브를 생성하면됩니다 pax. 파일 이름 (변환 된 것 제외), 내용, 시간 및 모드는 유지되지만 파일 소유권은 사용자에게 재설정됩니다 (루트로 실행되지 않은 경우).

mountavfs
cd "~/.avfs$PWD/old.tgz#"
pax -w -s '!bar!baz!' -s '!bar/!baz/' . | gzip >new.tgz

GNU Tar은 --transform최소한 2010 년부터 파일 이름을 즉시 변경할 수있게 해왔습니다 . 예를 들어, scriptsandoneliners.blogspot.com/2019/11/…
A.Danischewski에서

@ A.Danischewski를 --transform사용하면 아카이브를 빌드하거나 추출 할 때 파일 이름을 바꿀 수 있습니다. 그러나 압축을 풀지 않고 아카이브의 파일 이름을 어떻게 바꾸 나요? (추출은 좋은 해결책이 아닙니다. 디스크 공간이 충분하지 않거나 소유권 정보를 보존 할 권한이 없거나 타임 스탬프를 정확하게 보존 할 수있는 권한이 없을 수 있습니다 ...)
Gilles

그래, 네 방금 "GNU tar는 회원의 이름을 바꾸는 능력이 없다"는 게시물 상태를 보았습니다. 기존 아카이브 내에서 이름을 변경하려면 archivemount를 사용하여 디렉토리에 마운트하고 원하는 이름을 변경하고 마운트 해제 할 수 있습니다.
A.Danischewski 오전

3

sr_의 핵과 Gilles의 대답은 모두 매우 좋아 보이지만 rpmbuild를 실행하는 동안 문제가 대상 tarball의 루트 디렉토리 이름 인 경우 다른 해결책으로 %setup매크로를 재정 의하여 필요한 디렉토리 이름을 바꿀 수 있습니다.

(당신은 대체 특히, 적응 및 실제 구성이를 수정해야합니다 같은 것을 old-dir하고 desired-dir당신이를 오른쪽 압축 해제 도구를 사용하여) ~/.rpmmacros:

%setup cd ../BUILD \
rm -rf cd-player \
bunzip2 -dc ../SOURCES/%{name}-%{version}.tar.bz2 | tar -xvvf - \
if [ $? -ne 0 ]; then \
  exit $? \
fi \
mv <old-dir> <desired-dir> \
cd <desired-dir> \
cd ../BUILD/cd-player \
chmod -R a+rX,g-w,o-w .

가장 이국적인 상황이 아니라면 솔직히 그렇게하지는 않지만 당신의 경우가 될 수 있습니다 :)



1

못생긴 해킹이지만 tar심볼릭 링크로 장난하는 것이 도움이 될 수 있습니다 .

$ mkdir a b
$ date >> b/foo
$ tar zcvf b-foo.tgz b/foo
$ rm -rf b
$ ln -s a b

$ tar zxvf b-foo.tgz                                                              
x b/foo: Cannot extract through symlink b
tar: Error exit delayed from previous errors.
$ tar zxvPf b-foo.tgz                                                             
x b/foo
$ ls a
foo

그것에 대해 생각할 때, 아마도 rpm당신이에 대한 논쟁을 엉망으로 만들지 tar않을 것입니까? (편집 : 어쩌면 까다로운 tar래퍼 스크립트 $PATH가이 문제 를 해결할 수 있습니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.