如何更新tar压缩文件(非追加模式)?

4

我想要更新一个已有的tar文件,将其中的新的文件加入进去。

在GNU中,我看到:

4.2.3 更新归档文件

在上一节中,你学会了如何使用‘--append’来将一个文件添加到已有的归档文件中。相关的一个操作是‘--update’(‘-u’)。‘--update’操作通过比较指定归档成员的日期和同名文件的日期来更新tar归档文件。如果文件的修改日期比归档成员的日期更新,则把新的文件版本添加到归档文件中(就像‘--append’一样)

然而, 当我运行我的tar更新命令时,即使它们的修改日期完全相同,这些文件也被追加了。我只想追加那些要被打包的文件的修改日期比tar文件中已有的文件更新的文件...

tar -uf ./tarfile.tar /localdirectory/ >/dev/null 2>&1

目前,每次更新时,tar文件大小会翻倍...


是因为我忽略了保留开头斜杠的标志吗? - user420095
是的,你说得对。加上 -P 标志就可以工作了。或者你可以使用 cd /; tar -uf /path/file.tar localdirectory (由于某种奇怪的原因,我的 tar 版本无法通过连续调用与 tar -uf file.tar -C / localdirectory 命令一起使用)。 - praetorian droid
不可能的:tar 最初是指 磁带归档,你无法在磁带中间替换文件。 - Basile Starynkevitch
也许您会对 tardy(一个 tar 后处理器)感兴趣。http://tardy.sourceforge.net/ - Basile Starynkevitch
5个回答

3
您所描述的更新意味着存档文件中的文件被替换。如果新副本比存档中的文件小,它可以直接被重写。但如果新副本较大,则tar必须将现有的存档条目清零并进行追加。这样的更新会留下一些'\0'或其他未使用的字节,因此任何普通计算机用户都希望删除这样的部分,这可以通过“向上移动”包含存档内容的字节来完成(类似于C语言的memmove)。
然而,这样的原地移动操作涉及到寻址-读取-寻址-写入循环,成本非常高,特别是在考虑到磁带的情况下 - tar最初就是为磁带设计的设备,即具有不可与硬盘相比的寻址性能。这样的移动操作会很快损坏磁带。当然,WORM设备也不支持此移动操作。

2

如果您不想使用-P开关,tar -u...命令可以正确工作,前提是当前目录是我们要更新的目录的父目录,并且在tar命令中指定该目录的路径不是绝对路径。
例如:
我们想要更新目录/home/blabla/Dir。我们可以这样做:

cd /home/blabla  
tar -u -f tarfile.tar Dir  

通常情况下,更新必须与创建的位置相同,以便路径保持一致。同时也有其他可能性:
cd /home/blabla/Dir
tar -u -f /path/to/tarfile.tar .

1
您可以每次创建(而不是更新)归档文件,方法如下:tar -cvpf tarfile.tar *。这将解决归档文件每次增加一倍的问题。但是,它每次都会生成整个归档文件。

1

默认情况下,tar会从成员名称中删除前导的/,但在决定需要更新什么之后才执行此操作。

因此,如果您正在归档绝对路径,则需要cd /并使用相对路径,或添加-P / --absolute-names选项。

cd /
tar -uf "$OLDPWD/tarfile.tar" localdirectory/ >/dev/null 2>&1

tar -cPf tarfile.tar /localdirectory/ >/dev/null 2>&1
tar -uPf tarfile.tar /localdirectory/ >/dev/null 2>&1

然而,更新的项目仍将被追加。 tar(磁带归档)文件只能通过追加来修改。

8年来,竟然没有人在答案中给出实际的答案。 - OrangeDog

0

警告!当谈论“日期”时,它意味着任何日期,包括访问时间。

如果您的文件以任何这样的方式被访问(简单的ls -l就足够了),那么tar做的就是正确的!

您需要找到另一种方法来实现您想要的目标。可能使用一个哨兵文件,并查看其修改日期是否小于您希望追加的文件。


好的,你说的有道理。抱歉之前让你困惑了。那么,我猜tar是根据访问日期而不是修改日期进行操作?这似乎很愚蠢,因为每次运行tar -u时tar都会访问文件...哈哈 - user420095
你有三个日期与文件相关:访问时间(atime),inode修改时间(ctime)和内容修改时间(mtime)。如果其中任何一个发生变化,那么文件的“日期”也会改变。 - fge
附加说明:存在一些操作不会影响访问时间,例如 stat() 或者 lstat()。这很可能是tar在使用 -u 选项时采用的方式。 - fge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接