无法使用管道和 xargs 压缩大文件

无法使用管道和 xargs 压缩大文件

我尝试将 mysql 备份文件打包如下:

find /data/mysqldata \( ! -name "*mysql-bin*" -a ! -name "*.log" \) |
    xargs tar -zcf /data/backup.tgz

实际上,我用 Popen 执行了这个命令,并等待通过 select-poll 方法读取输出,但是,我发现有时备份文件已经很大后突然变得很小,就像 tar 程序重新启动一样。这种情况通常发生在目标文件非常大的时候,我对此很困惑。

答案1

使用 GNU tar

tar -cz -f /data/backup.tgz --exclude '*.log' --exclude 'mysql-bin.*' /data/mysqldata 

您遇到的问题是xargs执行了tar多次(至少两次)。第二次tar运行时,备份文件将“缩小”(被覆盖)。

这就是作用xargs。它使用尽可能多的参数执行一个实用程序,当它获得更多参数(在您的情况下是文件名)时,它会砍掉列表并在该实用程序的另一次调用中继续使用该列表。

问题发生了因为您将每个目录和文件名发送到xargs,生成了一个很长的列表。

答案2

直接将文件列表通过管道传递给归档命令,而不是xargs可以(在某些情况下)将列表拆分为多个归档器调用。

这里使用标准pax命令,但某些命令支持-print0/-0非标准扩展以增加可靠性:

find /data/mysqldata ! -name "*mysql-bin*" ! -name "*.log" -print0 |
  pax -0wd | gzip > file.tar.gz

(另请注意,-d如果没有它,所有文件都将被包含在内,因为归档/data/mysqldata(与排除模式都不匹配)将意味着像您的tar方法中那样归档所有内容)。

除此之外pax,许多tar实现都支持从标准输入获取文件列表,但实现之间通常具有不同的接口。

相关内容