我通常有几个问题,如何cron执行脚本,因为他们通常没有我的环境设置。是否有一种方法可以调用bash(?)以同样的方式cron,这样我就可以在安装它们之前测试脚本?
当前回答
我不相信有;我所知道的测试cron作业的唯一方法是设置它在未来运行一到两分钟,然后等待。
其他回答
已接受的答案确实提供了一种使用cron将使用的环境运行脚本的方法。正如其他人指出的那样,这并不是调试cron作业所需的唯一标准。
事实上,cron也使用非交互式终端,没有附加的输入等等。
如果这有帮助的话,我已经编写了一个脚本,可以轻松地运行命令/脚本,就像由cron运行一样。使用命令/脚本作为第一个参数调用它,就没问题了。
这个脚本也托管(可能更新)在Github上。
#!/bin/bash
# Run as if it was called from cron, that is to say:
# * with a modified environment
# * with a specific shell, which may or may not be bash
# * without an attached input terminal
# * in a non-interactive shell
function usage(){
echo "$0 - Run a script or a command as it would be in a cron job, then display its output"
echo "Usage:"
echo " $0 [command | script]"
}
if [ "$1" == "-h" -o "$1" == "--help" ]; then
usage
exit 0
fi
if [ $(whoami) != "root" ]; then
echo "Only root is supported at the moment"
exit 1
fi
# This file should contain the cron environment.
cron_env="/root/cron-env"
if [ ! -f "$cron_env" ]; then
echo "Unable to find $cron_env"
echo "To generate it, run \"/usr/bin/env > /root/cron-env\" as a cron job"
exit 0
fi
# It will be a nightmare to expand "$@" inside a shell -c argument.
# Let's rather generate a string where we manually expand-and-quote the arguments
env_string="/usr/bin/env -i "
for envi in $(cat "$cron_env"); do
env_string="${env_string} $envi "
done
cmd_string=""
for arg in "$@"; do
cmd_string="${cmd_string} \"${arg}\" "
done
# Which shell should we use?
the_shell=$(grep -E "^SHELL=" /root/cron-env | sed 's/SHELL=//')
echo "Running with $the_shell the following command: $cmd_string"
# Let's route the output in a file
# and do not provide any input (so that the command is executed without an attached terminal)
so=$(mktemp "/tmp/fakecron.out.XXXX")
se=$(mktemp "/tmp/fakecron.err.XXXX")
"$the_shell" -c "$env_string $cmd_string" >"$so" 2>"$se" < /dev/null
echo -e "Done. Here is \033[1mstdout\033[0m:"
cat "$so"
echo -e "Done. Here is \033[1mstderr\033[0m:"
cat "$se"
rm "$so" "$se"
我不相信有;我所知道的测试cron作业的唯一方法是设置它在未来运行一到两分钟,然后等待。
Cron默认只提供这个环境:
HOME用户的主目录 LOGNAME用户登录名 路径= / usr / bin: / usr / sbin SHELL = / usr / bin / sh
如果需要更多,可以在crontab中的调度表之前定义环境。
在我的例子中,cron正在使用sh执行我的脚本,它不能执行一些bash语法。 在我的脚本中,我添加了env变量SHELL:
#!/bin/bash
SHELL=/bin/bash
我发现的另一种简单方法(但可能容易出错,我仍在测试中)是在命令之前获取用户的配置文件。
编辑/etc/cron.d /脚本:
* * * * * user1 comand-that-needs-env-vars
会变成:
* * * * * user1 source ~/.bash_profile; source ~/.bashrc; comand-that-needs-env-vars
很脏,但它帮我完成了任务。是否有方法模拟登录?只是一个你可以运行的命令?Bash—登录不起作用。听起来这是更好的方法。
编辑:这似乎是一个可靠的解决方案:http://www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/
* * * * * root su --session-command="comand-that-needs-env-vars" user1 -l
推荐文章
- 检查bash变量是否等于0
- 只使用md5sum获取哈希值(没有文件名)
- 如何生成一个核心转储在Linux上的分段错误?
- 在Bash中测试非零长度字符串:[-n "$var"]或["$var"]
- 如何删除超过X小时的文件
- 如何创建Bash别名?
- 将所有变量从一个shell脚本传递到另一个?
- 如何删除shell脚本中文件名的扩展名?
- 使用xargs调用shell函数
- 如何限制从grep返回的结果的数量?
- 'find -exec'是Linux中的shell函数
- 将值从管道读入shell变量
- 在Bash中重用上一个命令的输出
- RE错误:在Mac OS X上的非法字节序列
- 对bash脚本函数中定义的变量使用curl POST