【问题标题】:Linux: Running a script manually from terminal works like a charm but when cron runs it, it fails, what could be the reason?Linux:从终端手动运行脚本就像一个魅力,但是当 cron 运行它时,它失败了,可能是什么原因?
【发布时间】:2016-02-16 12:34:51
【问题描述】:

为了每天备份 Puppet,我编写了以下脚本:

#!/bin/bash
today=$(date -I)
todaytime=$(date +'%H:%M')
log="/var/log/puppet_backup.log"
echo "Backup process started.... $todaytime $today" >>$log
cd /etc && tar cvzf - puppet | split --bytes=300MB - puppet.tar.gz. 2>&1>>$log
cd /var/lib && tar zcf var_lib_puppet.tar.gz puppet 2>&1>>$log
mkdir /system_backup/puppet/$today 2>&1>>$log
mv -v /etc/puppet.ta* /system_backup/puppet/$today/ 2>&1>>$log
mv -v /var/lib/var_lib_puppet.ta* /system_backup/puppet/$today/ 2>&1>>$log
echo "Backup process finished.... $todaytime $today" >> $log

当我手动运行此脚本时,它成功压缩了 Puppet 文件,创建了大约 10 个压缩文件并将它们正确移动到目标备份位置。

这是成功(手动)运行后的样子:

[root@puppet 2015-11-09]# ll
total 3377647
-rw-rw-r-- 1 root root 300000000 2015-11-09 13:15 puppet.tar.gz.aa
-rw-rw-r-- 1 root root 300000000 2015-11-09 13:16 puppet.tar.gz.ab
-rw-rw-r-- 1 root root 300000000 2015-11-09 13:16 puppet.tar.gz.ac
-rw-rw-r-- 1 root root 300000000 2015-11-09 13:16 puppet.tar.gz.ad
-rw-rw-r-- 1 root root 300000000 2015-11-09 13:16 puppet.tar.gz.ae
-rw-rw-r-- 1 root root 300000000 2015-11-09 13:16 puppet.tar.gz.af
-rw-rw-r-- 1 root root 300000000 2015-11-09 13:17 puppet.tar.gz.ag
-rw-rw-r-- 1 root root 300000000 2015-11-09 13:17 puppet.tar.gz.ah
-rw-rw-r-- 1 root root 177181611 2015-11-09 13:17 puppet.tar.gz.ai
-rw-rw-r-- 1 root root   7308901 2015-11-09 13:17 var_lib_puppet.tar.gz
[root@puppet 2015-11-09]#

但是当 crontab 运行这个脚本时,只创建了 3 个压缩文件并移动到了备份目标目录,是这样的:

[root@puppet 2015-11-15]# ll
total 1031678
-rw-r--r-- 1 root root 300000000 2015-11-15 04:59 puppet.tar.gz.aa
-rw-r--r-- 1 root root 300000000 2015-11-15 04:59 puppet.tar.gz.ab
-rw-r--r-- 1 root root 182204224 2015-11-15 04:59 puppet.tar.gz.ac
-rw-r--r-- 1 root root   7271603 2015-11-15 04:59 var_lib_puppet.tar.gz
[root@puppet 2015-11-15]#

您可能会猜到只有 3 个文件(而不是 9 个)意味着压缩过程没有正确完成,因此我无法使用这 3 个压缩文件恢复文件。

这是日志显示的内容:

Backup process started.... 04:59 2015-11-15
`/etc/puppet.tar.gz.aa' -> `/system_backup/puppet/2015-11-15/puppet.tar.gz.aa'
removed `/etc/puppet.tar.gz.aa'
`/etc/puppet.tar.gz.ab' -> `/system_backup/puppet/2015-11-15/puppet.tar.gz.ab'
removed `/etc/puppet.tar.gz.ab'
`/etc/puppet.tar.gz.ac' -> `/system_backup/puppet/2015-11-15/puppet.tar.gz.ac'
removed `/etc/puppet.tar.gz.ac'
`/var/lib/var_lib_puppet.tar.gz' -> `/system_backup/puppet/2015-11-15/var_lib_puppet.tar.gz'
removed `/var/lib/var_lib_puppet.tar.gz'
Backup process finished.... 04:59 2015-11-15

手动运行脚本或通过 cron 运行脚本之间存在差异的原因可能是什么?

【问题讨论】:

  • 请付出一些努力,让它对我们来说更具可测试性。您似乎在运行中压缩不同的文件。首先使用完全相同的文件自行调试,并尽可能使用较小的文件,以便您可以发布示例进行测试。此外,监控所有命令的退出状态(特别是设置pipe_fail 选项以避免忽略错误)。
  • 顺便说一句:将 2>&1>>$log 替换为 >>$log 2>&1 以在您的日志文件中查看 stderr。
  • 感谢@Cyrus,刚刚更换了它,将再次测试它。
  • 在 cron 中运行,您的 PATH 可能不包含所有使用的程序。正如建议的那样,捕获 stderr 是发现此类问题的第一步。

标签: bash cron backup puppet


【解决方案1】:

您是否尝试过检查 cron 中的限制 (ulimit)?

我注意到在 cron 运行中创建的最后一个文件比其他文件小,这可能意味着 cron 中存在其他不适用于命令行的限制(cron 的环境比平均命令行)。 这样的限制可能会影响您的拆分命令。

【讨论】:

  • 压缩包的最后一部分在这两种情况下都较小。这只是表明它的大小在任何一种情况下都不能被 300000000 字节整除。在失败情况下,整体大小更小似乎表明tar 在这种情况下过早终止。我想这可能反映了ulimit 问题,但我觉得这值得怀疑。
  • 会不会和“管道尺寸”有关?
  • 很难说。我建议在 cron 中捕获 'ulimit -a' 和 'env' 的输出,并将其与您在命令行上得到的结果进行比较。
  • 我对比了 cron ulimit -a 和 root ulimit -a,它们完全一样。
【解决方案2】:

我怀疑是权限问题。

您是否尝试过以 root 身份运行 cron?

https://superuser.com/questions/170866/how-to-run-a-cron-job-as-a-specific-user

【讨论】:

  • 脚本已经配置在 root 的 cron 下,但我尝试编辑它以在 crontab 配置中的命令前添加 root 用户,但无济于事。
  • 奇怪,我也很想知道。捕获 stderr 后是否发现更多错误?
  • @ItaiGanot,如果您在强制模式下运行 SELinux,它仍然可能是权限问题。 Cron 通常提供与交互式 shell 不同的 SELinux 上下文。如果 SELinux 在运行过程中拒绝访问某个文件,那么 tar 可能会在运行过程中失败。
猜你喜欢
  • 2022-01-06
  • 2012-11-04
  • 2022-09-30
  • 2019-11-16
  • 2021-03-19
  • 2021-06-27
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多