我希望某个脚本(rails rake 任务)始终在我的服务器上运行 - 它基本上使用实时源填充我的数据库。我可以创建一个屏幕(http://linux.die.net/man/1/screen)并轻松运行任务,但我想自动化它,以防它失败或停止(每当我部署到生产时,它就会停止)。
我创建了一个完美执行此操作的脚本:
# my_script
#!/bin/bash
start_myscreen () {
screen -dmS myscreen bash -c 'cd /var/app/current/; rake my_task RAILS_ENV=production'
}
if screen -list | grep -q "No Sockets found"; then
echo "no screens available"
echo "starting myscreen"
start_myscreen
else
echo "screens available!"
if screen -list | grep -q "myscreen"; then
echo "myscreen exists - restarting"
screen -X -S myscreen quit
else
echo "myscreen does NOT exist - creating now"
fi
start_myscreen
echo "Finished!"
fi
它的设计使得无论如何,屏幕“myscreen”都应该在脚本完成时启动 rake 任务。显然在生产中我不会每分钟运行脚本,这目前仅用于测试。当通过以下方式从终端执行时,该脚本可以完美运行:
./my-script
当我使用这个非常简单的 crontab 运行它时,就会出现问题:
* * * * * ./my-script
奇怪的是,脚本正确地输出了所有内容(基于从 crontab 通过邮件发送给我的消息),但当我运行时,我没有看到 cron 执行后运行的任何屏幕:
screen -list
很奇怪。
顺便说一句 - 服务器运行 64 位 Amazon Linux(我相信是红帽)
谢谢你的帮助。
答案1
首先,请注意 crontab 中的当前目录是您的主目录。您应该将脚本的完整路径放入 crontab 中。但是,由于您的脚本正在执行,所以这不是问题。
可能的问题是您的脚本需要在正常会话中设置的环境变量。 Cron 作业在最小环境下运行,您的.profile
未加载。
在许多系统上,~/.pam_environment
甚至可以为 cron 作业读取。请注意,这不是 shell 脚本,~/.pam_environment
仅支持受限语法。
如果你不能使用.pam_environment
,你可以.profile
明确阅读:
* * * * * . ~/.profile && ./my-script
您没有看到任何错误,因为它们是在屏幕窗口内发出的,并且屏幕随后立即关闭。将-L
选项添加到您的screen
调用中,最好是添加一个logfile
指令到您的.screenrc
,以使屏幕记录 rake 的输出,以防发生这种情况。