提取 tar 存档时删除目录结构

问题描述 投票:0回答:2

假设我使用

tar -czvf subdir.tgz subdirectory/*
在服务器 A 上创建了一个 tar 存档。如果我在服务器 B 上有一个并行结构,我已将这个 tarball 复制到其中,并且我现在想要破坏同一子目录 - 包括删除该子目录中 tar 存档中不存在的任何文件 - 我 could
cd 
进入服务器 B 上的父目录,
rm -rf subdirectory
,然后
tar -xzvf subdir.tgz

有没有一种方法可以做到这一点而不必先运行

rm

作为测试,我在服务器 B 的

subdirectory/dummy/
处放置了一个虚拟目录,然后运行
tar -xzvf subdir.tgz --recursive-unlink
,但令我惊讶的是,
subdirectory/dummy/
仍然在那里。我想我误解了
--recursive-unlink
的作用。

编辑========== 这是一个例子。我创建两个目录,它们代表两个不同服务器上的两个“镜像”目录(将它们视为服务器“a”和服务器“b”)。在目标目录('b')中,我创建了一个额外的目录和一些不会出现在 tar 存档中的文件。我预计这些会被破坏并删除。本质上,完成后我想要目录“b”中的只是目录“a”中的文件。但是,从示例中可以看出,尽管

--unlink-first
--recursive-unlink
,解压后多余的目录和文件仍然存在。

-bash-3.2$ mkdir tartest
-bash-3.2$ cd tartest
-bash-3.2$ mkdir a
-bash-3.2$ mkdir b
-bash-3.2$ cd a
-bash-3.2$ mkdir xyz
-bash-3.2$ cd xyz
-bash-3.2$ touch test.1
-bash-3.2$ touch test.2
-bash-3.2$ cd ../
-bash-3.2$ touch test.3
-bash-3.2$ cd ../b
-bash-3.2$ mkdir abc
-bash-3.2$ cd abc
-bash-3.2$ touch test.4
-bash-3.2$ cd ../../a
-bash-3.2$ tar cvf ../archive.tar ./*
./test.3
./xyz/
./xyz/test.2
./xyz/test.1
-bash-3.2$ cd ../b
-bash-3.2$ tar -xf ../archive.tar --unlink-first --recursive-unlink
-bash-3.2$ ls
total 16K
drwxr-xr-x 4 iponly168797 iponly168797 4.0K Jan 27 13:58 .
drwxr-xr-x 4 iponly168797 iponly168797 4.0K Jan 27 13:57 ..
drwxr-xr-x 2 iponly168797 iponly168797 4.0K Jan 27 13:56 abc
-rw-r--r-- 1 iponly168797 iponly168797    0 Jan 27 13:56 test.3
drwxr-xr-x 2 iponly168797 iponly168797 4.0K Jan 27 13:56 xyz
-bash-3.2$ ls xyz
total 8.0K
drwxr-xr-x 2 iponly168797 iponly168797 4.0K Jan 27 13:56 .
drwxr-xr-x 4 iponly168797 iponly168797 4.0K Jan 27 13:58 ..
-rw-r--r-- 1 iponly168797 iponly168797    0 Jan 27 13:56 test.1
-rw-r--r-- 1 iponly168797 iponly168797    0 Jan 27 13:56 test.2
tar directory-structure
2个回答
2
投票

--recursive-unlink
仅删除文件和目录(如果它阻止您提取新文件)。根据您的目的,添加
--unlink-first
。使用这两个选项,新 tar 中的文件和目录
not
都将被删除。

这对我来说是这样的:

ott@hv:~/tmp/tar $ tar cvf a.tar a
a/
a/test.txt
a/b/
a/c/
a/a/
ott@hv:~/tmp/tar $ cd b
ott@hv:~/tmp/tar/b $ tar xvf ../a.tar
a/
a/test.txt
a/b/
a/c/
a/a/
ott@hv:~/tmp/tar/b $ cd ../a
ott@hv:~/tmp/tar/a $ rmdir b
ott@hv:~/tmp/tar/a $ rm test.txt
rm: reguläre leere Datei »test.txt« entfernen? y
ott@hv:~/tmp/tar/a $ cd ..
ott@hv:~/tmp/tar $ tar cvf a.tar a
a/
a/c/
a/a/
ott@hv:~/tmp/tar $ cd b
ott@hv:~/tmp/tar/b $ tar xvf ../a.tar --unlink-first --recursive-unlink
a/
a/c/
a/a/
ott@hv:~/tmp/tar/b $ ls -lR
.:
insgesamt 8
drwxr-xr-x 4 ott ott 4096 31. Okt 19:21 a

./a:
insgesamt 16
drwxr-xr-x 2 ott ott 4096 28. Okt 21:31 a
drwxr-xr-x 2 ott ott 4096 28. Okt 21:31 c

./a/a:
insgesamt 0

./a/c:
insgesamt 0
ott@hv:~/tmp/tar/b $ tar --version
tar (GNU tar) 1.20

也许你有不同的焦油?


0
投票

虽然,我在这里扮演一个掘墓人的角色,但我认为,这篇文章仍然引导一些人走向错误的方向,认为

--recursive-unlink
的行为并不像你期望的那样。这就是为什么我想详细说明
--recursive-unlink
,它确实可以用作
rm -rf
的直接替代品。暂时忘记
--unlink-first
选项,因为您的情况不需要它。

我的 tar 版本是

tar (GNU tar) 1.35

我从以下包含文件和文件夹的目录结构开始:

$ find .           
.
./a
./a/both
./a/both/both.file
./a/both/only.a.file
./a/only.a.file
./a/only.a.folder
./a/only.a.folder/only.a.file
./b
./b/both
./b/both/both.file
./b/only.b.file
./b/only.b.folder
./b/only.b.folder/only.b.file

然后我从文件夹创建 tar 存档(备份)并将其解压到 b:

$ tar czvf a.tar.gz -C $(pwd)/a .
./
./both/
./both/both.file
./both/only.a.file
./only.a.file
./only.a.folder/
./only.a.folder/only.a.file

$ tar xzvf a.tar.gz --recursive-unlink -C $(pwd)/b
./
./both/
./both/both.file
./both/only.a.file
./only.a.file
./only.a.folder/
./only.a.folder/only.a.file

该命令成功覆盖目录,删除“only.b.folder”和“only.b.file”。它还更新两个源中存在的目录以包含“both/only.a.file”。

$ find  
.
./a
./a/both
./a/both/both.file
./a/both/only.a.file
./a/only.a.file
./a/only.a.folder
./a/only.a.folder/only.a.file
./b
./b/both
./b/both/both.file
./b/both/only.a.file
./b/only.a.file
./b/only.a.folder
./b/only.a.folder/only.a.file
./a.tar.gz

我使用“-C”选项强制相对路径而不使用 cd 到目录。为了完整起见,以下是 tar 文件的内容:

$ tar tzf a.tar.gz 
./
./both/
./both/both.file
./both/only.a.file
./only.a.file
./only.a.folder/
./only.a.folder/only.a.file

qed

© www.soinside.com 2019 - 2024. All rights reserved.