crontab执行Shell脚本时内部Ruby命令被忽略不生成文件问题
问题根因分析
- 工作目录不匹配:你使用
sudo crontab -e编辑的是root用户的定时任务,crontab执行时默认工作目录是root的家目录/root,Ruby脚本中用相对路径"users.txt"写入文件,生成的文件会落到/root/users.txt,后续Shell脚本读取/home/luis/users.txt自然找不到目标文件。 - rbenv环境缺失:rbenv是用户luis私有的Ruby版本管理工具,root用户执行时默认没有加载luis的rbenv环境配置,即使写了Ruby可执行文件的绝对路径,也可能因为缺少必要环境变量导致Ruby执行失败。
- Shell语法兼容问题:你的Shell脚本用了bash专属的
[[ ]]语法,crontab中用/usr/bin/sh调用脚本可能出现语法兼容问题,导致执行中断。 - 权限问题:
/home/luis/.rbenv/shims/ruby的执行权限可能未对root开放,或者luis家目录的权限限制root读取、执行相关文件。
排查步骤
- 先给Shell脚本加调试日志定位错误,在
md5_validation.sh开头添加两行:
exec 2>> /tmp/cron_debug.log set -x
等待1分钟后查看/tmp/cron_debug.log的报错内容,即可确认具体故障点。
- 验证root执行是否复现问题:手动运行
sudo /usr/bin/sh /home/luis/md5_validation.sh,如果和crontab执行效果一致,就可以确定是执行用户/环境的问题。 - 检查执行工作目录:在Shell脚本开头加一行
echo $PWD >> /tmp/cron_pwd.log,确认crontab执行时的工作目录是否符合预期。
解决方案
- 修正Ruby脚本的路径依赖,把相对路径改成绝对路径:
把linux_users.rb中的
file = File.open("users.txt", "w")
修改为
file = File.open("/home/luis/users.txt", "w")
- 修正执行环境和调用规则:
- 如果无需root权限执行任务,建议切换为luis用户的定时任务:用luis用户执行
crontab -e,写入定时规则,同时给脚本加执行权限:
chmod +x /home/luis/md5_validation.sh
crontab规则修改为:
*/1 * * * * /home/luis/md5_validation.sh
- 如果必须用root执行任务,在Shell脚本开头加载luis的rbenv环境,添加两行:
export PATH="/home/luis/.rbenv/shims:/home/luis/.rbenv/bin:$PATH" eval "$(rbenv init -)"
同时确认root对/home/luis/.rbenv/shims/ruby有执行权限,对/home/luis目录有读和执行权限。
- 修正Shell调用规则:把crontab中的
/usr/bin/sh改成/bin/bash,避免语法兼容问题:
*/1 * * * * /bin/bash /home/luis/md5_validation.sh
修改完成后先手动执行脚本验证功能正常,再启动crontab,检查/home/luis/users.txt和/var/log/下的两个日志文件是否按预期更新即可。
内容的提问来源于stack exchange,提问作者Kaido
相关产品推荐
相关产品推荐

