tar:以可能的点斜线开头可靠地提取成员

tar:以可能的点斜线开头可靠地提取成员

假设我有两个以略有不同的方式生成的 tar 档案:

$ tar tvf archive1.tar 
-rw-r--r-- root/root 567 2016-09-18 14:28 member1
-rw-r--r-- root/root 1696 2016-09-18 14:28 member2
$ tar tvf archive2.tar 
-rw-r--r-- root/root 567 2016-09-18 14:28 ./member1
-rw-r--r-- root/root 1696 2016-09-18 14:28 ./member2

如何提取 member1可靠地从两个档案中获取?我通过管道接收 tar,生成器不在我的控制之下,虽然我可以多次运行管道,但如果没有必要,我真的不想这样做。

附言:

$ tar xOvf archive1.tar member1 > /dev/null
member1
$ tar xOvf archive2.tar member1 > /dev/null
tar: member1: Not found in archive
tar: Exiting with failure status due to previous errors

答案1

看起来命令行开关 --no-anchored可以实现你想要的功能。从tar(1) 手册页(阅读或至少扫描它们确实非常有用)

--无锚定
模式在任何“/”之后匹配(排除的默认设置)

tar -tvf test
-rw-rw-r-- iain/iain         0 2016-09-18 16:14 ./member1
-rw-rw-r-- iain/iain         0 2016-09-18 16:14 ./member2

然后

tar -xvf test  member1
tar: member1: Not found in archive
tar: Exiting with failure status due to previous errors

进而

tar -xvf test --no-anchored member1
./member1

答案2

我也有过同样的经历。tar 作为事实上的标准实用程序,文档记录得如此之少,真是令人费解!我们大多数人身边没有丹,所以不幸的是...

我的用例涉及 tar 存档,其中一些是由我无法控制的软件生成的,手头的任务是提取名为“./opt/”或“opt/”的顶级目录。这是自动化 VM 映像过程的一部分,我显然希望它能够稳定地运行。

我想到的远非通用解决方案,但在我有限的范围内满足了我的需求。如果您需要提取大量顶级目录,并且处理事先不知道顶级目录名称的情况,则它不会很好地通用。

GNU tar 有一个--transform=选项可以使用 seds运算符,但不幸的是,在应用转换之前会执行命令行模式匹配。但是,基于我很乐意点赞的 @user9517 的回答,我想出了以下优雅的解决方案,但无论如何,这个糟糕的黑客攻击都能完成工作。这个想法是匹配opt/路径中的任何位置,并使用转换将碰巧在顶级之外的任何地方虚假匹配的文件重定向opt/到具有转换的临时路径,在提取后删除。完整命令如下:

tar xvf $tarfile --no-anchored \
                 --transform='s:^\(\./\)\?[^o][^p][^t]/:.deleteme/&:' \
                 --show-transformed-names \
        opt/

sed 类变换分解如下

^              only at the path start
\(\./\)\?      match ./ if present
[^o][^p][^t]   followed by any three characters that do not make "opt"
/              followed by /

替换部分&中的 代表原始路径,以避免任何可能的冲突。v--show-transformed-names仅用于记录提取的名称。


POC。请注意虚假且不需要的目录sys/opt/。每次提取之前都会清理 cwd。

带有前缀的 tar 打包./

kkm@buba:~/.tmp/tarext$ tar tvf ../tar.withdot.tar
drwxr-xr-x kkm/kkm           0 2020-01-07 21:26 ./
drwxr-xr-x kkm/kkm           0 2020-01-07 21:26 ./dev/
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 ./dev/file1.dev
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 ./dev/file2.dev
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 ./dev/file3.dev
drwxr-xr-x kkm/kkm           0 2020-01-07 21:29 ./opt/
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 ./opt/file1.opt
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 ./opt/file2.opt
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 ./opt/file3.opt
drwxr-xr-x kkm/kkm           0 2020-01-07 21:26 ./sys/
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 ./sys/file1.sys
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 ./sys/file2.sys
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 ./sys/file3.sys
drwxr-xr-x kkm/kkm           0 2020-01-07 21:26 ./sys/opt/
-rw-r--r-- kkm/kkm         100 2020-01-07 20:45 ./sys/opt/file1.opt
-rw-r--r-- kkm/kkm         100 2020-01-07 20:45 ./sys/opt/file2.opt
-rw-r--r-- kkm/kkm         100 2020-01-07 20:45 ./sys/opt/file3.opt
kkm@buba:~/.tmp/tarext$ tar xvf ../tar.withdot.tar --no-anchored --transform='s:^\(\./\)\?[^o][^p][^t]/:.deleteme/&:' --show-transformed-names opt/
./opt/
./opt/file1.opt
./opt/file2.opt
./opt/file3.opt
.deleteme/sys/opt/
.deleteme/sys/opt/file1.opt
.deleteme/sys/opt/file2.opt
.deleteme/sys/opt/file3.opt
kkm@buba:~/.tmp/tarext$ rm -rf .deleteme/ ; ls -RA
.:
opt

./opt:
file1.opt  file2.opt  file3.opt

没有前缀的 tar 打包:

kkm@buba:~/.tmp/tarext$ tar tvf ../tar.nodot.tar
drwxr-xr-x kkm/kkm           0 2020-01-07 21:26 dev/
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 dev/file1.dev
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 dev/file2.dev
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 dev/file3.dev
drwxr-xr-x kkm/kkm           0 2020-01-07 21:29 opt/
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 opt/file1.opt
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 opt/file2.opt
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 opt/file3.opt
drwxr-xr-x kkm/kkm           0 2020-01-07 21:26 sys/
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 sys/file1.sys
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 sys/file2.sys
-rw-r--r-- kkm/kkm         100 2020-01-07 19:09 sys/file3.sys
drwxr-xr-x kkm/kkm           0 2020-01-07 21:26 sys/opt/
-rw-r--r-- kkm/kkm         100 2020-01-07 20:45 sys/opt/file1.opt
-rw-r--r-- kkm/kkm         100 2020-01-07 20:45 sys/opt/file2.opt
-rw-r--r-- kkm/kkm         100 2020-01-07 20:45 sys/opt/file3.opt
kkm@buba:~/.tmp/tarext$ tar xvf ../tar.nodot.tar --no-anchored --transform='s:^\(\./\)\?[^o][^p][^t]/:.deleteme/&:' --show-transformed-names opt/
opt/
opt/file1.opt
opt/file2.opt
opt/file3.opt
.deleteme/sys/opt/
.deleteme/sys/opt/file1.opt
.deleteme/sys/opt/file2.opt
.deleteme/sys/opt/file3.opt
kkm@buba:~/.tmp/tarext$ rm -rf .deleteme/ ; ls -RA
.:
opt

./opt:
file1.opt  file2.opt  file3.opt

相关内容