我正在尝试创建一个备份脚本。我已经设法让这个脚本在 CentOS 6.7 机器上正常工作,现在正在尝试让它在 Debian 7 上正常工作。
我遇到了一个问题,我似乎无法通过 Google 或此网站上找到的任何信息来解决。在讨论这个问题之前,我会尝试解释一下我的情况。
在 CentOS 上,我使用以下命令查找过去 24 小时内更改的文件,$SOURCEDIR
并使用xargs
仅将这些文件放入$ARCHIVE
.如果未找到文件,则会弹出一条消息。
find $SOURCEDIR -mtime -1 -print | xargs -r tar rcvf $ARCHIVE || { echo "No files have been changed in the past 24 hours. Exiting script ..." ; exit 1; }
我知道使用tar rcvf
可以调用以下错误消息:
您不能指定多个“-Acdtrux”或“--test-label”选项
然而,这似乎不会发生在 CentOS 机器上。它做在 Debian 机器上,因此我已从命令r
中删除了该命令tar
。我首先添加此内容的原因是因为我想避免存档在find
返回超过 100 个结果时被覆盖。
现在讨论实际问题。每当我跑步时
find $SOURCEDIR -mtime -1 -print
$SOURCEDIR
正如预期的那样,我获得了过去 24 小时内更改的文件列表。但是,每当我运行包含管道符号和xargs
如下命令的完整命令时:
find $SOURCEDIR -mtime -1 -print | xargs -r tar cvf $ARCHIVE || { echo "No files have been changed in the past 24 hours. Exiting script ..." ; exit 1; }
我实际上看到了find
命令打印全部文件来自$SOURCEDIR
得到一个档案,其中包括全部来自的文件$SOURCEDIR
,我不明白为什么。任何帮助将不胜感激。
答案1
正如其他人所指出的,您的命令的问题在于它包含目录,并且 tar 递归地归档它们。如果最近修改了某个目录,则该目录及其子目录中的所有文件都会被包含在内,无论它们是否已修改。
如果您不想备份目录元数据,则只需告诉find
不要打印目录名称即可。仅仅省略根目录是不够的:子目录也会发生同样的情况。
find "$SOURCEDIR" -mtime -1 ! -type d -print | xargs -r tar -rcf "$ARCHIVE"
使用 xargs文件名包含空格和其他一些特殊字符时失败。这很容易解决:使用-exec
而不是xargs
.
find "$SOURCEDIR" -mtime -1 ! -type d -exec tar -rcf "$ARCHIVE" {} +
如果您想备份目录元数据,请find
打印所有内容,然后告诉tar
不要递归到子目录。由于find
正在执行递归,tar
因此不需要。
find "$SOURCEDIR" -mtime -1 -exec tar -rcf "$ARCHIVE" --no-recursion {} +
通过这种方法,您可以避免使用tar 调用tar -rc
,而是通过首先创建仅包含根目录的存档,然后批量追加到其中来解决重复 tar 调用的问题。 (为什么是根目录?因为 GNU tar 害怕创建一个空的存档。)
tar -cf "$ARCHIVE" --no-recursion "$SOURCEDIR"
find "$SOURCEDIR" -mindepth 1 -mtime -1 -exec tar -rf "$ARCHIVE" --no-recursion {} +
答案2
find $SOURCEDIR -mtime -1
还包含$SOURCEDIR
在输出中,需要在进一步处理之前将其删除
使用grep -vx
一个可以定义要排除的特定行。
find $SOURCEDIR -mtime -1 -print | grep -xv "$SOURCEDIR" | xargs -r tar cvf $ARCHIVE || { echo "No files have been changed in the past 24 hours. Exiting script ..." ; exit 1; }
答案3
xargs
如果调用两次,您不仅会遇到问题tar
,如果文件名包含换行符等特殊字符,您也会遇到问题。
您应该放弃使用xargs
andtar
并使用find
with cpio
:
find $SOURCEDIR -mtime -1 -print0 | cpio --create -0 --verbose \
--format=ustar -O $ARCHIVE
ustar
为您提供 POSIX.1 兼容的 tar 文件$ARCHIVE
。
答案4
当您执行时,find $SOURCEDIR -mtime -1 -print
第一个结果将是文件夹 $SOURCEDIR 本身。这就是为什么一切都包括在内。
您必须排除第一个结果 或$SOURCEDIR
。