use*_*456 8 tar zip compression gzip
假设我/root/bigfile
在 100GB 的系统上有一个 80GB 的文件,并且想将此文件放入存档中 /root/bigarchive.tar
我显然需要在将其添加到存档中的同时删除该文件。因此我的问题是:
如何在将文件添加到存档的同时删除文件?
单个文件的未压缩 tar 存档由标题、文件和尾随填充组成。所以你的主要问题是如何将 512 字节的标题添加到文件的开头。您可以首先使用标题创建想要的结果:
tar cf - bigfile | dd count=1 >bigarchive.tar
Run Code Online (Sandbox Code Playgroud)
然后复制文件的前 10G。简单地说,我们假设您的 dd 一次可以读/写 1Gib:
dd count=10 bs=1G if=bigfile >>bigarchive.tar
Run Code Online (Sandbox Code Playgroud)
我们现在从原始文件中释放复制的数据:
fallocate --punch-hole -o 0 -l 10GiB bigfile
Run Code Online (Sandbox Code Playgroud)
这将用不占用文件系统空间的稀疏零替换数据。以这种方式继续,将 a 添加skip=10
到 next dd
,然后将fallocate
起始偏移量增加到-o 10GiB
。最后添加一些空字符来填充最终的 tar 文件。
如果您的文件系统不支持,fallocate
您可以做类似的事情,但从文件末尾开始。首先将文件的最后 10GB 复制到一个名为part8
. 然后使用该truncate
命令减小原始文件的大小。以类似的方式继续,直到您有 8 个文件,每个文件为 10Gibyte。然后,您可以连接标头和part1
to bigarchive.tar
,然后删除part1
,然后连接part2
并删除它,依此类推。
删除文件并不一定像您认为的那样。这就是为什么在类 UNIX 系统中调用系统调用unlink
而不是delete
. 从手册页:
unlink() deletes a name from the filesystem. If that name was the last
link to a file and no processes have the file open, the file is deleted
and the space it was using is made available for reuse.
If the name was the last link to a file but any processes still have
the file open, the file will remain in existence until the last file
descriptor referring to it is closed.
Run Code Online (Sandbox Code Playgroud)
因此,只要数据压缩器/归档器正在读取文件,该文件就会一直存在,占用文件系统中的空间。
如果您使用 GNUtar
命令,则可以使用以下--remove-files
选项:
--删除文件
将文件添加到存档后将其删除
tar -cvf files.tar --remove-files my_directory
Run Code Online (Sandbox Code Playgroud)