【问题标题】:tar filenames with spaces in a one line crontab style tar / find command单行 crontab 样式中带有空格的 tar 文件名 tar / find 命令
【发布时间】:2017-05-29 21:05:23
【问题描述】:

当从 crontab 运行以下命令时,遇到文件名中包含空格的文件时会发生 tar 错误。

/tar -C / -zcvf /root/archive-of-files-with-spaces-in-filename.tar.gz `find /var/www/html -mmin -1450 -print | sed 's|^/||'`

将开关更改为 -print0 或完全移除 -print 开关并不能解决问题:

/tar -C / -zcvf /root/archive-of-files-with-spaces-in-filename.tar.gz `find /var/www/html -mmin -1450 -print0 | sed 's|^/||'`

/tar -C / -zcvf /root/archive-of-files-with-spaces-in-filename.tar.gz `find /var/www/html -mmin -1450 | sed 's|^/||'`

tar 也会抛出同样的错误。

如何重写命令以允许将带有空格的文件名提供给 tar 而不被分解为不存在的目录名?

文件名产生的错误示例: "2016-12-15 名称文件修复exportICS.php"

tar:var/www/html-calendar.northpawfamilycloud.xyz/pages/2016-12-15: 无法统计:没有这样的文件或目录
tar:名称:无法统计:没有这样的文件或目录
tar:文件:无法统计:没有这样的文件或目录
tar:修复:无法统计:没有这样的文件或目录
tar:exportICS.php:无法统计:没有这样的文件或目录

注意 | sed 's|^/||'` 去掉前导斜杠发现所以 tar 错误“删除前导斜杠不会发生。

【问题讨论】:

  • 为什么根目录下有tar?保存可执行文件的地方很奇怪。
  • 在 crontab 中,命令行是 1 1 * * * /bin/tar 我在命令行中使用 #tar 进行测试,因为 /bin 在我的服务器的 PATH 环境变量中

标签: bash find crontab tar ubuntu-16.04


【解决方案1】:

由于您要做的唯一过滤是从/var/www/html 下的名称中删除前导斜杠,因此您可以单独使用tar — 避免find 出现无数问题:

tar -C / -czvf /root/archive-of-files-with-spaces-in-filename.tar.gz var/www/html

给定一个目录,tar 备份目录的内容。如果您在/var/html 下有子目录,则您的存档可能是所需大小的两倍。这个不会比需要的大。


显然,find 命令包含选项。在这种情况下,您必须以另一种方式做事:

(cd /; find var/www/html -type f -mmin -1450 -print0) |
 tar -C / --null -T - --czvf /root/archive-of-files-with-spaces-in-filename.tar.gz

cd /; find var/html 避免了 find 的前导斜杠。 -print0 使用空终止符作为文件名。 --null 告诉 tar 期望文件名以空结尾; -T - 表示从标准输入读取文件名列表。

如果您愿意,可以将所有内容放在一行中。这不是我会这样做的方式。我将创建一个由cron (crontab) 系统运行的脚本来完成这项工作,特别是因为如果我正在运行它,输出文件名将不可避免地带有时间戳,并且它可能会识别出哪个正在备份站点等。要备份的站点将是脚本的一个参数,由crontab 条目提供。这是我的偏好;有很多人在他们的crontab 文件中写长行。

此外,GNU tar(嘈杂地)省略了存档名称中的前导斜杠,因此在 GNU tar 生成的 tar 文件中永远不会有绝对名称:

tar: Removing leading `/' from member names

这意味着您可以避免使用子 shell,而只需使用 find /var/www/html … 来生成名称,同时显示警告消息。因为无论如何你都有详细的输出,这不太可能是个大问题。

【讨论】:

  • 我将 tar 命令与 find 一起使用,因为我通常会在 find 中添加开关以启用各种增量备份技术,例如在 find 语句中添加 --mmin -1450 以仅归档具有修改时间戳的文件24 小时 10 分钟前。
  • /var/www/html 包含一个小站点 / /var/ww/html1 包含下一个小站点,依此类推。
【解决方案2】:

用空格归档

用反斜杠转义空格或引用文件名。示例:

tar czvf /my/path/filename\ with\ spaces.tgz files...

如果要归档的文件名称中有空格

使用find ... -print0 分隔带有NULL 的文件名tar ... --null 以仅考虑以NULL 结尾的文件。来自GNU tar documentation

find /path ... -print0 | tar  ... --null -T -

【讨论】:

  • 这是遗漏的问题。问题不在于档案名称——它无论如何都没有空格。问题是处理 files... 中名称中有空格的条目。
  • 这适用于 tar 一个带有空格的文件,但不适用于一次压缩数百个文件的命令。
  • @JonathanLeffler:是的,你是对的。我确实编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
  • 2011-08-19
  • 2015-07-09
相关资源
最近更新 更多