https://www.v2ex.com/t/252709 我之前发了个贴,得到大家帮助,解决了。
我后来又重新写了个其他脚本 sh 文件,设置 crontab 自行。脚本里面全部用完整的绝对路径,除了 echo touch rm 这样的命令没用路径开头(这些不用吧)。
自己手工运行,一切正常; crontab 定时就不执行。
另外用的是 debian 系统,没发现哪里有 crontab 的记录,只在 syslog 里面有看到执行时间,是否成功失败没日志。
网络上搜索了下,所谓的开启 cron 的日志功能,也都是 ubantu centos 的,确认都符合我用的 debian 7 系统。
有没有谁能说下 crontab 里面设定执行还有那些方面要注意?
Ubuntu 下可以注意下执行时间,比如原本是这样
0 6 * * * /etc/test.sh
改成这样
00 06 * * * /etc/test.sh
还有注意 chmod +x /etc/test.sh
谢谢楼上,不过我用的是 debian 7.x
脚本手工输入自行也是正常的。
准备稍后去 man cron 看看。
把脚本和 crontab 内容贴出来啊
debian7 用上面的那个格式应该是没问题的 0 6 * * * /etc/test.sh
补充下,还有系统时间,美国服务器时间与北京时间约有 12 小时差别,另外建议发下日志
不执行总有日志吧,执行错误?还是找不到 sh 文件?
你的 sh 脚本是 bash 的还是?
这样运行呢? sh /path/test.sh
可能是时区的问题。注意 crontab 调用的时区和你 timezone 看到的时区不一样。
rm 也要绝对路径吧
不把脚本和 crontab 内容贴出来,说别的都是耍流氓
/var/mail/{设定 cron 的用户名}
补贴代码和错误提示的求助都是耍流氓
估计还是路径没弄好。在 sh 文件里先用 cd $(dirname $0) || exit 1 切换到脚本所在目录,然后统一用相对路径吧。
反正我的 crontab 里面连 cp 都是 /bin/cp
把你的脚本写成这样的开头 -x ,命名为 /etc/foo.sh
再写 /etc/bar.sh 脚本,内容为:
/>/etc/foo.sh >> /var/log/foo.log
在 crontabl 里写
X X X ... /etc/bar.sh
X 是你原来设定的时间,为了调试,可以先设置成 1 分钟执行一次
观察 /var/log/foo.log
终于 ok 了
之前在 crontab 里面是这样写:
*/15 * * * * /usr/bin/txt2html.sh
自动执行不成功;手工运行这个 sh 是完全正常。
现在这个 vps 改成这样:*/15 * * * * /bin/bash /usr/bin/txt2html.sh 才正常。
但是我其他 vps 上的脚本文件,例如 myreboot.sh (每天重启之前删除下一些不用的文件)都是采用的第一种写法,也都正常。
另外: debian 7 的 cron 日志开启是这样的(网络上搜索的都不靠谱):
cron -L 15
这样就是所有的 cron 日子都记录,包括正常和错误。
弱弱地问下楼主,查下 crontab -u yourusername -e 是撒样子,能看到设置的任务吗?
我以前刚学的时候发现设置的任务,用户没有权限执行.
这里我只看到你说的命令,所以我想是不是权限问题
额,一般为了保险都是: sh /usr/bin/txt2html.sh ,或者避免程序执行的路径问题可以: cd /usr/bin/;sh ./txt2html.sh
看来和 sh 有关。我还 bash 后正常。
刚刚看到你的回复我试了下 sh /usr/bin/txt2html.sh
/usr/bin/txt2html.sh: 18: /usr/bin/txt2html.sh: Syntax error: "(" unexpected
同样 bash /usr/bin/txt2html.sh 不会报错。
这个 txt2html 的脚本是网上找的。原本功能部分我没改动,就是改了 txt 和 html 文件名。
附脚本(挺长)
!/bin/sh
file_input='txt.log'
file_output='txt2html.html'
td_str=''
function create_html_head(){
echo -e "
$file_input
"
}
function create_table_head(){
echo -e "
"
}
function create_td(){
if [ -e ./"$1" ]; then
echo $1
td_str=`echo $1 | awk 'BEGIN{FS="|"}''{i=1; while(i<=NF) {print ""$i" | ";i++}}'`
echo $td_str
fi
}
function create_tr(){
create_td "$1"
echo -e "
$td_str
" >> $file_output
}
function create_table_end(){
echo -e "
"
}
function create_html_end(){
echo -e ""
}
function create_html(){
rm -rf $file_output
touch $file_output
create_html_head >> $file_output
create_table_head >> $file_output
while read line
do
echo $line
create_tr "$line"
done < $file_input
create_table_end >> $file_output
create_html_end >> $file_output
}
create_html
好的,以后 crontab 里面是完全不能省,就像楼上说的 cp 命令都要写成 /bin/cp 保险。 sh 文件前面也加上 sh 或者 bash
不写解释器能给你执行就怪了= =…
另外 sh 和 bash 的区别: http://stackoverflow.com/questions/5725296/difference-between-sh-and-bash
1 系统 cron 和用户 cron 的格式不同
2 bash 和 dash 的语法不同
3 bash xx.sh 和 /path/to/xx.sh 使用的 shell 有可能不同
4 cron 调用和命令行调用的环境变量不同
你提问太缺乏精确描述了
!/bin/sh --> #!/bin/bash
+1
shebang 写错了
多了空格
是不是用 source abc.sh 执行的脚本?
debian 我看了 确实是把 sh 连接到 dash
我用的那个脚本估计对 dash 兼容性问题,应该是 bash 兼容,所以脚本原本的解析器在 debian 上用 dash 解析报错;换 bash 后正常。
这个应该就是问题所在了。
谢谢。
是你提到的 2 和 3 的原因。
谢谢了。
还有就是创建文件的用户和执行 crontab 的用户最好一致,我踩过这样的坑,还有安装 crontab 后没有开启 cron 服务的坑
比如 https://github.com/starlightme/v2ex-daily-sgin-in/issues/2
环境变量的坑,脚本里面最好加上 source /etc/profile
/>source /etc/profile
或者这样
* * * * * source /etc/profile && /your/shell/path.sh
还有记得把输出重定向
* * * * * /your/path.sh >/dev/null 2>&1
或者* * * * * /your/path.sh >>/your/path.log 2>>&1
我来几个大坑。我都踩过。
1 、重定向放在 crontab -e 中啊,别放在 sh 中,除非 sh 自己有重定向。类似:
0 4 * * 0 /root/frame/restart_weekly.sh >> restart_weekly.log 2>&1
2 、 crontab -e 之前如果修改过 timezone ( cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 这种),编辑 crontab 之后,一定要重启 crond 服务哇, service crond restart. 不然他是按照之前的时区执行的哇。
3 、 sh 一定要加上 export 全路径, sh 一定要加上 export 全路径, sh 一定要加上 export 全路径,重要的事情要说 3 遍, crond 不是 ssh 登陆上起自带路径导入,如果没有事先 export ,貌似好像连 cd ls cp 都找不到滴。
例子:
/>PATH=/root/jdk1.6.0_45/bin:/usr/local/nginx/sbin:/root/ncftp-3.2.5/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/root/info/
export PATH
pkill -9 java
cd /root/frame
/>./clearAccount.sh
./runServer.sh
直接 crontab 里写上 PATH 就行了
$(/usr/bin/which command)
不是更好?当然,除了自定义的路径
/>脚本说明
IFS=
一个健壮的脚本,一开始就应该把 shebang 、 IFS 、 PATH 设置好:
脚本说明
IFS='
'
PATH=/bin:/usr/bin:...
export PATH
没看到你的脚本,但我知道 Ubuntu 有个 Bug ,就是必须 Cron 文件最后一定要有空行, 有空行,有空行!!!!
在 debian 只遇到 path 问题,似乎命令写全路径甚至 cd 到脚本路径也无效,至于是 sh 还是 bash 这在脚本的第一行就该定义了
/>PATH=/bin:/usr/bin:/sbin:/usr/sbin
echo "`(date +"%m/%d/%Y %T")` `free | grep "Mem" | awk 'BEGIN{ORS=""}{ print "Memory Space : Total "$2 " KB";print " Used "$3" KB";print " Free "$4" KB\012";}'`" >> /tmp/log
你需要 https://github.com/javan/whenever
试试换一个 crontab -e 编辑器
vim 的话试试 zz 保存
环境变量的问题可以这样, cronrab -e,最上面加上一行, PATH=/bin:/sbin:/usr/bin:/usr/local/bin 还有其它的就继续添加
今天也遇到了这个问题,最后用你的方法解决了,感谢。
不过你的命令有点错误,套用后无法执行改为:cd /usr/bin/;txt2html.sh 就可以了