还是 crontab 定时执行问题,真被搞败了 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
itsme
V2EX    Linux

还是 crontab 定时执行问题,真被搞败了

  • &bsp;
  •   itsme 2016-01-23 12:29:08 +08:00 9291 次点击
    这是一个创建于 3600 天前的主题,其中的信息可能已经有所发展或是发生改变。
    t/252709 我之前发了个贴,得到大家帮助,解决了。

    我后来又重新写了个其他脚本 sh 文件,设置 crontab 自行。脚本里面全部用完整的绝对路径,除了 echo touch rm 这样的命令没用路径开头(这些不用吧)。

    自己手工运行,一切正常; crontab 定时就不执行。

    另外用的是 debian 系统,没发现哪里有 crontab 的记录,只在 syslog 里面有看到执行时间,是否成功失败没日志。

    网络上搜索了下,所谓的开启 cron 的日志功能,也都是 ubantu centos 的,确认都符合我用的 debian 7 系统。

    有没有谁能说下 crontab 里面设定执行还有那些方面要注意?
    42 条回复    2018-01-22 12:44:05 +08:00
    Devin
        1
    Devin  
       2016-01-23 12:47:53 +08:00 via iPhone
    Ubuntu 下可以注意下执行时间,比如原本是这样
    0 6 * * * /etc/test.sh
    改成这样
    00 06 * * * /etc/test.sh

    还有注意 chmod +x /etc/test.sh
    itsme
        2
    itsme  
    OP
       2016-01-23 12:51:57 +08:00
    谢谢楼上,不过我用的是 debian 7.x
    脚本手工输入自行也是正常的。

    准备稍后去 man cron 看看。
    Tink
        3
    Tink  
    PRO
       2016-01-23 12:52:55 +08:00
    把脚本和 crontab 内容贴出来啊
    Devin
        4
    Devin  
       2016-01-23 12:57:05 +08:00 via iPhone
    @itsme debian7 用上面的那个格式应该是没问题的 0 6 * * * /etc/test.sh
    补充下,还有系统时间,美国服务器时间与北京时间约有 12 小时差别,另外建议发下日志
    Busy
        5
    Busy  
       2016-01-23 13:18:53 +08:00
    不执行总有日志吧,执行错误?还是找不到 sh 文件?
    你的 sh 脚本是 bash 的还是?

    这样运行呢? sh /path/test.sh
    zander
        6
    zander  
       2016-01-23 13:19:33 +08:00
    可能是时区的问题。注意 crontab 调用的时区和你 timezone 看到的时区不一样。
    just1
        7
    just1  
       2016-01-23 13:21:53 +08:00 via Android
    rm 也要绝对路径吧
    skydiver
        8
    skydiver  
       2016-01-23 13:22:57 +08:00   1
    不把脚本和 crontab 内容贴出来,说别的都是耍流氓
    47jm9ozp
        9
    47jm9ozp  
       2016-01-23 13:30:13 +08:00
    /var/mail/{设定 cron 的用户名}
    47jm9ozp
        10
    47jm9ozp  
       2016-01-23 13:30:33 +08:00
    补贴代码和错误提示的求助都是耍流氓
    zdhxiong
        11
    zdhxiong  
       2016-01-23 13:32:07 +08:00
    估计还是路径没弄好。在 sh 文件里先用 cd $(dirname $0) || exit 1 切换到脚本所在目录,然后统一用相对路径吧。
    venster
        12
    venster  
       2016-01-23 13:32:27 +08:00
    反正我的 crontab 里面连 cp 都是 /bin/cp
    xuboying
        13
    xuboying  
       2016-01-23 13:43:53 +08:00
    把你的脚本写成这样的开头 #!/bin/sh -x ,命名为 /etc/foo.sh
    再写 /etc/bar.sh 脚本,内容为:
    #!/bin/sh
    /etc/foo.sh >> /var/log/foo.log

    在 crontabl 里写

    X X X ... /etc/bar.sh

    X 是你原来设定的时间,为了调试,可以先设置成 1 分钟执行一次
    观察 /var/log/foo.log
    itsme
        14
    itsme  
    OP
       2016-01-23 14:31:01 +08:00
    终于 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 日子都记录,包括正常和错误。
    yumijie
        15
    yumijie  
       2016-01-23 14:34:18 +08:00
    弱弱地问下楼主,查下 crontab -u yourusername -e 是撒样子,能看到设置的任务吗?

    我以前刚学的时候发现设置的任务,用户没有权限执行.

    这里我只看到你说的命令,所以我想是不是权限问题
    iyaozhen
        16
    iyaozhen  
       2016-01-23 14:34:31 +08:00
    @itsme 额,一般为了保险都是: sh /usr/bin/txt2html.sh ,或者避免程序执行的路径问题可以: cd /usr/bin/;sh ./txt2html.sh
    itsme
        17
    itsme  
    OP
       2016-01-23 14:39:47 +08:00
    @Havee 看来和 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 "<html>
    <head>
    <meta http-equiv="Content-Type" >
    <body>
    <h1>$file_input</h1>"
    }

    function create_table_head(){
    echo -e "<table border="1">"
    }

    function create_td(){
    # if [ -e ./"$1" ]; then
    echo $1
    td_str=`echo $1 | awk 'BEGIN{FS="|"}''{i=1; while(i<=NF) {print "<td>"$i"</td>";i++}}'`
    echo $td_str
    # fi
    }

    function create_tr(){
    create_td "$1"
    echo -e "<tr>
    $td_str
    </tr>" >> $file_output
    }

    function create_table_end(){
    echo -e "</table>"
    }

    function create_html_end(){
    echo -e "</body></html>"
    }


    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
    itsme
        18
    itsme  
    OP
       2016-01-23 14:41:43 +08:00
    @iyaozhen 好的,以后 crontab 里面是完全不能省,就像楼上说的 cp 命令都要写成 /bin/cp 保险。 sh 文件前面也加上 sh 或者 bash
    Valyrian
        19
    Valyrian  
       2016-01-23 15:03:51 +08:00 via iPad
    不写解释器能给你执行就怪了= =…
    另外 sh 和 bash 的区别: http://stackoverflow.com/questions/5725296/difference-between-sh-and-bash
    julyclyde
        20
    julyclyde  
       2016-01-23 15:04:33 +08:00
    1 系统 cron 和用户 cron 的格式不同
    2 bash 和 dash 的语法不同
    3 bash xx.sh 和 /path/to/xx.sh 使用的 shell 有可能不同
    4 cron 调用和命令行调用的环境变量不同

    你提问太缺乏精确描述了
    vivisidea
        21
    vivisidea  
       2016-01-23 15:14:08 +08:00
    # !/bin/sh --> #!/bin/bash
    xuboying
        22
    xuboying  
       2016-01-23 15:23:43 +08:00 via Android
    xuboying
        23
    xuboying  
       2016-01-23 15:24:01 +08:00 via Android
    shebang 写错了
    xuboying
        24
    xuboying  
       2016-01-23 15:24:35 +08:00 via Android
    多了空格
    wangleineo
        25
    wangleineo  
       2016-01-23 15:42:09 +08:00
    是不是用 source abc.sh 执行的脚本?
    itsme
        26
    itsme  
    OP
       2016-01-23 16:03:43 +08:00
    @Valyrian
    debian 我看了 确实是把 sh 连接到 dash

    我用的那个脚本估计对 dash 兼容性问题,应该是 bash 兼容,所以脚本原本的解析器#/bin/sh 在 debian 上用 dash 解析报错;换 bash 后正常。

    这个应该就是问题所在了。

    谢谢。
    itsme
        27
    itsme  
    OP
       2016-01-23 16:04:43 +08:00
    @julyclyde 是你提到的 2 和 3 的原因。
    谢谢了。
    jimmy66
        28
    jimmy66  
       2016-01-23 17:16:35 +08:00
    还有就是创建文件的用户和执行 crontab 的用户最好一致,我踩过这样的坑,还有安装 crontab 后没有开启 cron 服务的坑
    jimmy66
        29
    jimmy66  
       2016-01-23 17:16:41 +08:00
    qiaoxin
        30
    qiaoxin  
       2016-01-23 18:30:28 +08:00
    环境变量的坑,脚本里面最好加上 source /etc/profile
    #!/bin/sh
    source /etc/profile
    或者这样
    * * * * * source /etc/profile && /your/shell/path.sh
    qiaoxin
        31
    qiaoxin  
       2016-01-23 18:36:02 +08:00
    还有记得把输出重定向
    * * * * * /your/path.sh >/dev/null 2>&1
    或者* * * * * /your/path.sh >>/your/path.log 2>>&1
    yuchting
        32
    yuchting  
       2016-01-23 18:48:52 +08:00
    我来几个大坑。我都踩过。
    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 都找不到滴。
    例子:

    #!/bin/sh
    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
    #./backup.sh
    ./clearAccount.sh
    ./runServer.sh
    skydiver
        33
    skydiver  
       2016-01-23 18:51:02 +08:00
    @yuchting 直接 crontab 里写上 PATH 就行了
    Bardon
        34
    Bardon  
       2016-01-24 00:00:11 +08:00
    $(/usr/bin/which command)
    不是更好?当然,除了自定义的路径
    uuspider
        35
    uuspider  
       2016-01-24 02:06:09 +08:00
    #!/bin/bash
    # 脚本说明
    IFS=
    uuspider
        36
    uuspider  
       2016-01-24 02:09:40 +08:00
    一个健壮的脚本,一开始就应该把 shebang 、 IFS 、 PATH 设置好:

    #!/bin/bash
    # 脚本说明
    IFS='
    '
    PATH=/bin:/usr/bin:...
    export PATH
    steveneo
        37
    steveneo  
       2016-01-24 06:32:51 +08:00
    没看到你的脚本,但我知道 Ubuntu 有个 Bug ,就是必须 Cron 文件最后一定要有空行, 有空行,有空行!!!!
    datocp
        38
    datocp  
       2016-01-25 08:24:31 +08:00 via Android
    在 debian 只遇到 path 问题,似乎命令写全路径甚至 cd 到脚本路径也无效,至于是 sh 还是 bash 这在脚本的第一行就该定义了

    #!/bin/sh
    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
    huobazi
        39
    huobazi  
       2016-01-25 11:09:44 +08:00
    xbaofeng
        40
    xbaofeng  
       2016-01-25 13:46:34 +08:00
    试试换一个 crontab -e 编辑器
    vim 的话试试 zz 保存
    qiaoxin
        41
    qiaoxin  
       2016-01-26 20:37:16 +08:00
    环境变量的问题可以这样, cronrab -e,最上面加上一行, PATH=/bin:/sbin:/usr/bin:/usr/local/bin 还有其它的就继续添加
    chanssl
        42
    chanssl  
       2018-01-22 12:44:05 +08:00
    @iyaozhen #16 今天也遇到了这个问题,最后用你的方法解决了,感谢。
    不过你的命令有点错误,套用后无法执行改为:cd /usr/bin/;txt2html.sh 就可以了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2339 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 15:49 PVG 23:49 LAX 07:49 JFK 10:49
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86