首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
V2EX  ›  Linux

crontab 能否实现每 50 秒执行一次定时任务

  •  
  •   horek · 224 天前 · 4613 次点击
    这是一个创建于 224 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我有一个需要定时 50 秒执行一次任务的需求,想了半天,只能实现每 10 秒执行一次、30 秒执行一次,就是不知道 50 秒执行一次能不能设置,求指教
    41 回复  |  直到 2019-03-21 10:01:08 +08:00
        1
    ysc3839   224 天前 via Android
    大概不行。可以设置成 10 秒执行一次,然后记录一下执行次数,到 5 了才实际执行代码。
        2
    xfspace   224 天前 via Android   ♥ 1
    #!/usr/bin/env bash
    sleep 50
    balabala

    crontab -e
    * * * * * /something/bashfile
        3
    sarie   224 天前
    @xfspace 厉害了
        4
    zhangxiaodao   224 天前
    你都会设置 30 秒了,50 秒为啥不能设置?
        5
    MajorAdam   224 天前
    之前试过用 cron 表达式应该是不行的
        6
    hanbaobao2005   224 天前
    试一下
    */50 * * * * *
    是不是可行
        7
    hayi   224 天前
    @hanbaobao2005 这肯定不行,60 秒一个周期,30 秒内的都可以这样。大于的就不行
        8
    Patrick95   224 天前
    * * * * * /bin/bash -l -c "/path/to/executable; sleep 50 ; /path/to/executable"
        9
    horek   224 天前
    @hayi 我也觉得大于 30 秒的都不行
        10
    glasslion   224 天前   ♥ 2
    @hayi
    @horek

    cron 表达式 */n 的含义是,当秒数 /分钟数...能被 n 整除时执行, 而不是每 n 分钟执行.
        11
    zhfish   224 天前
    https://crontab.guru
    最少是 1 分钟
        12
    hugee   224 天前
    @xfspace
    @Patrick95 你两这个不仍然 1 分钟一次?


    @hanbaobao2005 你这个不是 50 分钟才一次?

    lz 说的是每 50 秒一次吧?@horek
        13
    radc   224 天前   ♥ 3
    其实搭配 sleep 是可以实现任意秒数间隔的 就是蛋疼了一点
    比如想要 10s 间隔,那就取个分钟整数,做 sleep 10/20/30/40/50/60 6 个 cronjob (*/1 * * * *)
    要 30s 间隔,就 sleep 30/60,两个 cronjob, (*/1 * * * *)

    比如楼主想要 50s,那就取整到 300s,弄这么几个....... 每 300 秒装填 6 个任务,分别以 50 秒间隔来执行。
    ```
    */5 * * * * (sleep 50; echo `date` >> /tmp/50s.log)
    */5 * * * * (sleep 100; echo `date` >> /tmp/50s.log)
    */5 * * * * (sleep 150; echo `date` >> /tmp/50s.log)
    */5 * * * * (sleep 200; echo `date` >> /tmp/50s.log)
    */5 * * * * (sleep 250; echo `date` >> /tmp/50s.log)
    */5 * * * * (sleep 300; echo `date` >> /tmp/50s.log)
    ```
    测试输出是这样,符合预期 挺 2b 的方法.... but it works! 😂
    ```
    Wed Mar 13 12:15:51 CST 2019
    Wed Mar 13 12:16:41 CST 2019
    Wed Mar 13 12:17:31 CST 2019
    Wed Mar 13 12:18:21 CST 2019
    Wed Mar 13 12:19:11 CST 2019
    Wed Mar 13 12:20:01 CST 2019
    Wed Mar 13 12:20:52 CST 2019
    Wed Mar 13 12:21:42 CST 2019
    Wed Mar 13 12:22:32 CST 2019
    ```
        14
    seeusoon   224 天前
    这种需求可以直接考虑 supervise+py 来弄,逻辑简单清晰易于维护更新
    具体逻辑用 py 实现,supervise 负责保证 py 进程不退出
        15
    fuergaosi   224 天前 via iPhone
    @seeusoon supervise 现在应该还是不支持 py3 吧
        16
    xuboying   224 天前
    这是不是一个 A->B 问题?
        17
    sfqtsh   224 天前 via Android
    用 at 命令
        18
    LoliconInside   224 天前 via Android
    While True:
    time.sleep 50
        19
    reus   224 天前
    有 systemd 的 timer 不用,非要用过时的 crond ?
        20
    7654   224 天前
    while [ 1 ]
    do
    sleep 50
    done &
        21
    jasonyang9   224 天前
    用 SystemD Timers
        22
    Trim21   224 天前 via Android
    @zhangxiaodao 因为*/50 会在每个小时的 0 和 50 分钟执行,而不是每 50 分钟执行一次…
        23
    Cooky   224 天前 via Android
    50 秒 和 60 秒 最小公倍数 300 秒
    你定个 5 分钟一次的周期
    一次执行的时候 跑一次 sleep 一下 6 回就够了
        24
    wwqgtxx   224 天前
    用 systemd timers,能精确到 us 级别,随便你想要多少秒
        25
    aimiyooo   224 天前
    crontab 不支持,可以用 supervisor+死循环脚本实现
        26
    MrUser   224 天前
    第一步:每 30 秒调用一次中间脚本 do.sh (小于你的 50 秒就可以):
    ```
    * * * * * /home/user/bin/do.sh >>/var/log/crontab-do.sh.log 2>&1
    * * * * * sleep 30; /home/user/bin/do.sh >>/var/log/crontab-do.sh.log 2>&1
    ```

    第二步:在中间脚本 do.sh 里判断是不是够 50 秒了(当前时间戳能被 50 整除说明 50 秒到了):
    ```
    #!/bin/bash
    dateTime=`date "+%Y-%m-%d %H:%M:%S"`
    timeStamp=`date -d "$dateTime" +%s`
    remainder=$(($timeStamp % 50))
    if [ $remainder = 0 ]; then
    echo "50 秒了,该执行你的脚本了,在这里调用你的脚本"
    fi
    ```
        27
    MrUser   224 天前
    有 BUG,收回上边的回复。。。。( BUG:需要 60 条 crontab 才行。。。。)
        28
    inf0sys   224 天前
    crontab 小时位 /72 试试; )
        29
    taolu   224 天前
    time_step=50
    for (( i=0; i<300; i=(i+${time_step}) )); do
    shell
    sleep ${time_step}
    done

    */5 * * * * shell
        30
    Raymon111111   224 天前
    10 秒来一次, 用计数器控制是个简单又可行的方案.
        31
    yc8332   224 天前
    cron 不是分钟级的吗?秒级的应该要自己实现吧
        32
    deepdark   224 天前 via Android
    @xfspace 老哥你这 50 秒之后,一秒执行一次啊,你只是第一次执行推迟了 50 秒而已
        33
    zeroz   224 天前
    PHP 是世界上最好的语言!
    Swoole Timer 毫秒精度的定时器 https://wiki.swoole.com/wiki/page/p-timer.html
        34
    houm   224 天前
    设 6 条 Cron,试试可行不 @horek
    50 0/6 * * * ?
    40 1/6 * * * ?
    30 2/6 * * * ?
    20 3/6 * * * ?
    10 4/6 * * * ?
    0 5/6 * * * ?
        35
    hahaayaoyaoyao   223 天前 via Android
    @reus 同意
        36
    cpdyj0   223 天前
    要不就别用 crontab 了,写个脚本死循环 timeout 50,拿 systemd 监控,定时重启(防止内存泄漏,不知 bash 这方面是怎么做的)
        37
    gscoder   223 天前
    做不到,只能用计数器控制。但那样定时器和逻辑就耦合起来了,不太好。
        38
    cpdyj0   223 天前
    哦,bash 好像是类似引用计数那种东西(好像连计数也不存在的 [garbage-collection-in-bash]( https://stackoverflow.com/questions/14806296/garbage-collection-in-bash)
    所以倒是不必担心内存问题了,就是监控下别挂了
        39
    cpdyj0   223 天前
    @gscoder 写俩脚本 /手动斜眼
        40
    sujin190   223 天前
    https://github.com/snower/forsun

    推荐下之前写的工具,支持秒级定时,命令行和 crontab 类似

    安装
    pip install forsun

    启动
    forsund

    设置定时
    forsun "set show_date_to_home */50/0 * * * * * sh 'date >> /tmp/date.log'"

    查看定时列表
    forsun "ls *"

    删除定时
    forsun "rm show_date_to_home"

    时间设置还是多了第三个数字代表的是执行次数,0 代表一直执行,从设置这一刻往后 50 秒运行
        41
    Gempty   216 天前
    sleep 正解
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3018 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 23ms · UTC 10:55 · PVG 18:55 · LAX 03:55 · JFK 06:55
    ♥ Do have faith in what you're doing.