是否可以在tar归档文件中重命名目录?我的用例是,我有一个外部提供的RPM规范文件,该文件假定一个具有特定目录结构的tarball,并且我有一个外部提供的tarball,其顶级目录名称与该规范文件所期望的名称不匹配。我既不控制生成tarball的脚本,也不控制RPM规范文件,因此我无法更改其中任何一个以匹配另一个。
我一直在做的事情是解压缩,更改目录名称,然后创建一个新的tarball,但是我想知道是否有替代方法。
是否可以在tar归档文件中重命名目录?我的用例是,我有一个外部提供的RPM规范文件,该文件假定一个具有特定目录结构的tarball,并且我有一个外部提供的tarball,其顶级目录名称与该规范文件所期望的名称不匹配。我既不控制生成tarball的脚本,也不控制RPM规范文件,因此我无法更改其中任何一个以匹配另一个。
我一直在做的事情是解压缩,更改目录名称,然后创建一个新的tarball,但是我想知道是否有替代方法。
Answers:
这应该不是很困难,至少对于与旧格式兼容的档案而言,文件名存储在固定大小(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替代了cpio
和tar
)可以。但是,您不能pax
同时从存档中进行读取和写入。您可以做的是通过AVFS将档案公开为常规树,并使用创建新档案pax
。这将保留文件名(转换后的文件名除外),内容,时间和模式,但会向您重置文件所有权(除非以root用户身份执行)。
mountavfs
cd "~/.avfs$PWD/old.tgz#"
pax -w -s '!bar!baz!' -s '!bar/!baz/' . | gzip >new.tgz
--transform
从至少2010年开始,GNU Tar 就允许即时重命名文件。例如,请参阅:scriptsandoneliners.blogspot.com/2019/11/…–
--transform
允许您在构建或提取存档时重命名文件。但是,如何在不解压缩的情况下重命名存档中的文件呢?(提取不是一个好的解决方案:您可能没有足够的磁盘空间;您可能没有权限保留所有权信息;您可能没有能力完全保留时间戳记...)
sr_的hack和Gilles的回答都很好,但是如果您的问题只是目标tarball的根目录名称,则在运行rpmbuild时,另一种解决方案是重新定义%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 .
如果不是在最奇特的情况下,我不会诚实地这样做,但是您的情况可能是这样的:)
只需查看此页面,但在其他地方找到正确的答案:
http://www.rpm.org/max-rpm/s1-rpm-inside-macros.html
它说您可以将-n传递给%setup宏,以告诉rpmbuild tarball中顶级文件夹的名称。
丑陋的骇客,但也许对您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
可以解决这个问题。)