如何让任务每 a-b 分钟执行一次脚本 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
xiaohantx
V2EX    Linux

如何让任务每 a-b 分钟执行一次脚本

  •  
  •   xiaohantx
    xiaohantx 2020-09-15 14:17:36 +08:00 4256 次点击
    这是一个创建于 1855 天前的主题,其中的信息可能已经有所发展或是发生改变。

    */8 * * * * /bin/sh /www/wwwroot/xxxx.com/crontab.sh

    目前是 8 分钟一次

    rand_num=$(($RANDOM%300+60)) declare -i i=1; while ((i<rand_num)) do sleep 1 let i++ done php /www/wwwroot/xxx.com/run.php 

    每 8 分钟把任务提出来一次然后再延迟 1-5 分钟,但是这样就会出现两个任务在跑的情况。。。想单任务但是时间在 a-b 间任意

    34 条回复    2020-09-16 14:43:21 +08:00
    TaxKiz
        1
    TaxKiz  
       2020-09-15 14:35:30 +08:00
    #!/bin/bash

    export PATH='/bin:/sbin:/usr/bin:/usr/sbin'

    while true; do

    ps -ef | grep '/www/wwwroot/xxx.com/run.php' | grep -v '\bgrep\b' >/dev/null 2>&1

    if [$? != 0]; then

    rand_num=$(($RANDOM % 300 + 60))

    declare -i i=1

    while ((i < rand_num)); do
    sleep 1
    let i++
    done

    php /www/wwwroot/xxx.com/run.php

    unset -v rand_num i

    fi

    done
    xiaohantx
        2
    xiaohantx  
    OP
       2020-09-15 14:37:16 +08:00
    @TaxKiz crontab -e 里面的基础 8 分钟不变还是放在那是嘛
    xiaohantx
        3
    xiaohantx  
    OP
       2020-09-15 14:41:52 +08:00
    @TaxKiz 好像丢服务器线程跑满了,CPU 变成了 100%。。。
    TaxKiz
        4
    TaxKiz  
       2020-09-15 14:48:19 +08:00   1
    @xiaohantx 草率了,你加个 sleep

    ...
    unset -v rand_num i

    fi

    sleep 1

    done
    TaxKiz
        5
    TaxKiz  
       2020-09-15 14:48:50 +08:00   1
    @xiaohantx sleep 时自己定义
    knightdf
        6
    knightdf  
       2020-09-15 15:00:23 +08:00   1
    ```shell
    */a * * * * python -c 'import random; import time; time.sleep(random.randint(0, b-a) * 60)' && flock -x -n /www/wwwroot/xxx.com/run.php php /www/wwwroot/xxx.com/run.php
    ```
    xiaohantx
        7
    xiaohantx  
    OP
       2020-09-15 15:02:46 +08:00
    @TaxKiz 不好意思不是很会 shell
    日志报了个错
    `/www/server/cron/d4e8c583cbd42140a85eac6baabec0f5: line 12: [1: command not found`

    另外想问下我已经配置了定时任务,每 N (固定)分钟执行这个脚本,脚本里面的 sleep 是啥意思= =比如 1 分钟执行了这个 4 次然后随机时间还没到在后台定时这时候 sleep 是起到什么作用呢,不过感谢老哥
    zlowly
        8
    zlowly  
       2020-09-15 15:04:21 +08:00   1
    1 、可以在脚本里保证单实例执行,大概方式就是
    a)判断如果 lock 文件是否存在,如果存在则退出
    b)touch lock
    c)用 trap 在 exit 时候 rm lock
    2 、这个需求其实还是不很明确,就是如果上一次还没执行完就到下一次的预定时间了该办?
    3 、可以不用 crontab,用 atd 服务,然后脚本末尾用 at 指定下次执行时间。
    xiaohantx
        9
    xiaohantx  
    OP
       2020-09-15 15:09:30 +08:00
    @knightdf 是要写进 crontab 嘛,我直接 shell 脚本跑返回了
    ```
    /www/server/cron/d4e8c583cbd42140a85eac6baabec0f5: line 4: */1: No such file or directory
    ----------------------------------------------------------------------------
    ★[2020-09-15 15:08:19] Successful
    ----------------------------------------------------------------------------
    ```
    knightdf
        10
    knightdf  
       2020-09-15 15:10:54 +08:00
    @xiaohantx 这是一条 cron 啊
    TaxKiz
        11
    TaxKiz  
       2020-09-15 15:15:10 +08:00   1
    ```sh
    #!/bin/bash

    export PATH='/bin:/sbin:/usr/bin:/usr/sbin'

    # 替换成实际路径
    P='/xxx/run.php'

    while true; do

    # 检测进程是否存在
    ps -ef | grep $P | grep -v '\bgrep\b' >/dev/null 2>&1

    # 如果进程不存在, 执行 PHP 脚本
    if [ $? != '0' ]; then

    rnd_num=$(($RANDOM % 300 + 60))

    declare -i i=1

    while ((i < rand_num)); do
    sleep 1
    let i++
    done

    php $P

    unset -v rand_num i

    fi

    # 每 1 秒检测一次进程, 可自定义
    sleep 1

    done
    ```

    @xiaohantx
    xiaohantx
        12
    xiaohantx  
    OP
       2020-09-15 15:42:34 +08:00
    @knightdf 我是应该运行 crontab -e 然后粘贴进去嘛,然后 service crond restart 是嘛
    knightdf
        13
    knightdf  
       2020-09-15 15:44:16 +08:00   1
    @xiaohantx 参数做相应的更改后直接粘贴进去,不需要 restart
    xiaohantx
        14
    xiaohantx  
    OP
       2020-09-15 15:47:02 +08:00
    @TaxKiz sleep 我暂时没改默认的 1,rand_num=$(($RANDOM % 480 + 180))改为 2-8 分钟,但是输出还是一分钟一次,对了我这里试着用了宝塔的定时任务,定时执行时间是 1 分钟一次,不知道有没有影响
    xiaohantx
        15
    xiaohantx  
    OP
       2020-09-15 15:56:50 +08:00
    @knightdf
    */1 * * * * python -c 'import random; import time; time.sleep(random.randint(0, 2-1) * 60)' && flock -x -n /www/wwwroot/xxx.com/run.php php /www/wwwroot/xxx.com/run.php
    粘贴进去了好像会同时运行两次?理解的是这个时间 1 分钟基础时间然后随机 1-2 分钟,就是最快应该 2 分钟以上吧 2-3 分钟?
    xiaohantx
        16
    xiaohantx  
    OP
       2020-09-15 15:57:48 +08:00
    @knightdf 我注意到了,因为做的消息推送,每次发送,好像是发送完之后马上跟着再执行一次推送
    knightdf
        17
    knightdf  
       2020-09-15 16:15:40 +08:00
    @xiaohantx 不可能同时运行 2 次,这是一分钟一次,延迟 0 或者 1 分钟
    dier
        18
    dier  
       2020-09-15 16:19:15 +08:00
    declare -i s_number # 将变量声明为整数
    s_number=`cat /dev/urandom | tr -dc 1-6 | head -c 1`*60 # 随机出 1-5 之间的数乘以 60,得到秒数
    sleep $s_number # 睡眠指定秒数
    wait # 等待上面的命令执行完,即睡眠指定秒数再往下执行

    上面的放在你要执行的脚本前,触发定时任务后就会自动随机睡眠 1-5 分钟再执行
    xiaohantx
        19
    xiaohantx  
    OP
       2020-09-15 16:20:42 +08:00
    @knightdf 那还是之前那个原因嘛,每 1 分钟一次,比如一个 a 任务 3 分钟,b 任务 2 分钟,那第一个还没到时间 b 先执行了,然后 a 又执行了,但是这样应该也间隔一分钟吧.....有点懵,基础时间可以去掉嘛,只想给个区间时间,然后随机在这个区间进行执行任务
    treblex
        20
    treblex  
       2020-09-15 17:02:22 +08:00
    装个宝塔,或者 php 可以访问的话 直接用 url 监控
    xiaohantx
        21
    xiaohantx  
    OP
       2020-09-15 17:04:20 +08:00
    @dier emmm 那还是是会有个睡眠时间的增加吧。。类似于延迟,没办法稍微精准点控制,比如我想 3-8 分钟运行一次,没办法稍微精准点控制在范围内吗
    xiaohantx
        22
    xiaohantx  
    OP
       2020-09-15 17:05:32 +08:00
    @suke971219 宝塔的定时任务试固定的
    knightdf
        23
    knightdf  
       2020-09-15 17:32:52 +08:00
    @xiaohantx 你自己先把需求描述清楚吧
    mikurasa
        24
    mikurasa  
       2020-09-15 17:37:14 +08:00
    可以基于 cron 表达式+随机时间因子 和锁自己手写一个调度
    dier
        25
    dier  
       2020-09-15 17:42:07 +08:00
    @xiaohantx 你要求的就不是一个精确时间,怎么精准控制呢?要么 3 分钟,要么 8 分钟,你得确定执行间隔时间呀
    dier
        26
    dier  
       2020-09-15 17:53:09 +08:00   1
    想到了一个办法,不用睡眠等待,手动把定时任务写到 /etc/crontab 文件中,然后在你的脚本最后加上一段替换脚本,执行完脚本去更新这个文件中的间隔时间
    chogath
        27
    chogath  
       2020-09-15 20:35:54 +08:00
    短时间执行的可不可以考虑使用 延时队列呢? Redis 或者 MQ
    MagicalE
        28
    MagicalE  
       2020-09-15 21:23:04 +08:00
    是怕定时推送被检测嘛?
    xiaohantx
        29
    xiaohantx  
    OP
       2020-09-15 21:26:07 +08:00
    @MagicalE 是的 app 抓包的
    MagicalE
        30
    MagicalE  
       2020-09-15 23:12:59 +08:00
    @xiaohantx 我最近也在做类似功能,一个比较简单的 selenium 定时回复程序,定时执行总是被系统删除。

    windows 下只知道可以用计算机管理里面的基本任务来定时执行脚本,而那个基本任务的触发器必须指定具体时间,很头疼≡()≡
    ety001
        31
    ety001  
       2020-09-15 23:39:19 +08:00
    想要保证 crontab 单任务的话,可以试试 flock 给要执行的程序加锁。
    ety001
        32
    ety001  
       2020-09-15 23:41:38 +08:00
    随机时间放在 php 程序的开头,进入先 sleep 一个随机数,再执行。
    jinhan13789991
        33
    jinhan13789991  
       2020-09-16 09:39:02 +08:00
    简单,定时器执行任务脚本。脚本最后加上如下逻辑:删除定时器,再写入一个新的执行当前脚本的任务,执行时间是 a-b 分钟之后。
    more1sec
        34
    more1sec  
       2020-09-16 14:43:21 +08:00
    python 的 adscheduler 可以指定一个 cron 同时只能有 1 个实例在跑
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     934 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 19:54 PVG 03:54 LAX 12:54 JFK 15:54
    Do have faith in what you're doing.
    ubao 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