假设我使用
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
--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
也许你有不同的焦油?
虽然,我在这里扮演一个掘墓人的角色,但我认为,这篇文章仍然引导一些人走向错误的方向,认为
--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