我有一个每小时执行一次的 cron 脚本,它会获取一些输出(mysql 转储),通过 gzip 进行管道传输,然后目标覆盖同名文件。当我手动运行它时,root
文件被覆盖了。当它由 cron 守护程序运行时,文件名后附加了“.1”。这种情况一直发生,所以过了一段时间,我有很多文件,如下所示:
myfile.gz
myfile.gz.1
myfile.gz.1.1
myfile.gz.1.1.1
myfile.gz.1.1.1.1
等等。
ps aux|grep crond
显示守护进程正在作为 运行root
。
我试过了:
- 重命名原始文件,推送输出,然后在完成后删除旧文件,并且
- 在管道输出之前删除原始文件
但都没有按预期工作,我只是得到了.1.1.1.1
文件。
脚本看起来像这样(没什么特别的)并且位于 CentOS 框中/etc/cron.hourly
:
#!/bin/bash
DATE=`date +%H`
DIR="/abs/path/to/dir"
FILE="hourly-${DATE}.gz"
OPTS="..."
mysqldump $OPTS | gzip -9 > $DIR/$FILE
有人可以解释为什么这个简单的操作没有按预期运行吗?
答案1
最有可能的是,您的脚本是使用 Bash 功能编写的,但它是由 Bourne shell 运行的。#!/bin/bash
您的脚本的第一行是什么?请发布它,以便我们更好地帮助您。
编辑:
在旨在作为 cron 作业运行的脚本中,我总是指定程序的完整路径(例如mysqldump
和gzip
),因为 $PATH 变量和别名之类的内容将与交互式 shell 中的不同。这样,结果是可预测的。
答案2
尝试在脚本顶部的 bash 行后面添加这一行
set +C
这将关闭 bash 中的 noclobber 选项,因此应该覆盖该文件。
如果不是这样,那么它可能类似于由 cron 或您的整体环境设置的 gzip 别名。
答案3
我觉得这很奇怪,bash 有一个 noclobber 选项,它使得重定向不会覆盖文件。也许这是最新版本的一个类似新选项,但会创建一个 .1 文件?
是否有可能在 cronjob 中调用类似 logrotate 的程序,或者在它之前运行某些程序来移动文件 (logrotate)?您应该检查 /etc/crontab 并crontab -e
以 root 身份运行。
这是在某种云或共享托管网站上吗?也许提供商已经创建了某些东西来帮助减少他们的工单负载 :-)
答案4
不是gzip -c
?该选项用于写入 stdout 而不是文件。是否设置了GZIP
或GZIP_OPT
环境变量(其中包含 gzip 选项)?