V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wuyadaxian
V2EX  ›  程序员

[疑问]如何使用 cron 让脚本每 7 分钟执行一次?

  •  4
     
  •   wuyadaxian · 53 天前 · 12881 次点击
    这是一个创建于 53 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我的环境是 Ubuntu 22.04LTS 。
    要求是从现在或者某个时间点开始,每 7 分钟执行一次 test.sh 脚本。
    只能使用 crontab 来编写。
    只是讨论,真正实现的时候肯定用 bash 或者其他语言脚本更方便实现。
    第 1 条附言  ·  51 天前
    -------------2024.6.1----------------
    我们现在拥有了两种解法,如果还有其他解法请尽情探讨。
    一种穷举法,见#22 ,#32 ,#33 ,#34 ,#113
    一种复杂的 command 法,见#39 ,#40 ,#45 ,#51 ,#68 ,#96 ,#119
    -----------------------------
    穷举法:(需要增加偏移量的时候,调整周位置上的数字即可)
    #周一
    0-56/7 0-21/7 * * 1 command
    3-59/7 1-22/7 * * 1 command
    6-55/7 2-23/7 * * 1 command
    2-58/7 3-17/7 * * 1 command
    5-54/7 4-18/7 * * 1 command
    1-57/7 5-29/7 * * 1 command
    4-53/7 6-20/7 * * 1 command
    #周二
    2-58/7 0-21/7 * * 2 command
    5-54/7 1-22/7 * * 2 command
    1-57/7 2-23/7 * * 2 command
    4-53/7 3-17/7 * * 2 command
    0-56/7 4-18/7 * * 2 command
    3-59/7 5-29/7 * * 2 command
    6-55/7 6-20/7 * * 2 command
    #周三
    4-53/7 0-21/7 * * 3 command
    0-56/7 1-22/7 * * 3 command
    3-59/7 2-23/7 * * 3 command
    6-55/7 3-17/7 * * 3 command
    2-58/7 4-18/7 * * 3 command
    5-54/7 5-29/7 * * 3 command
    1-57/7 6-20/7 * * 3 command
    #周四
    6-55/7 0-21/7 * * 4 command
    2-58/7 1-22/7 * * 4 command
    5-54/7 2-23/7 * * 4 command
    1-57/7 3-17/7 * * 4 command
    4-53/7 4-18/7 * * 4 command
    0-56/7 5-29/7 * * 4 command
    3-59/7 6-20/7 * * 4 command
    #周五
    1-57/7 0-21/7 * * 5 command
    4-53/7 1-22/7 * * 5 command
    0-56/7 2-23/7 * * 5 command
    3-59/7 3-17/7 * * 5 command
    6-55/7 4-18/7 * * 5 command
    2-58/7 5-29/7 * * 5 command
    5-54/7 6-20/7 * * 5 command
    #周六
    3-59/7 0-21/7 * * 6 command
    6-55/7 1-22/7 * * 6 command
    2-58/7 2-23/7 * * 6 command
    5-54/7 3-17/7 * * 6 command
    1-57/7 4-18/7 * * 6 command
    4-53/7 5-29/7 * * 6 command
    0-56/7 6-20/7 * * 6 command
    #周日
    5-54/7 0-21/7 * * 7 command
    1-57/7 1-22/7 * * 7 command
    4-53/7 2-23/7 * * 7 command
    0-56/7 3-17/7 * * 7 command
    3-59/7 4-18/7 * * 7 command
    6-55/7 5-29/7 * * 7 command
    2-58/7 6-20/7 * * 7 command
    -----------------------------
    复杂 command 法:(需要增加偏移量 N 的时候:((data+%s)/60+N)%7 )
    * * * * * [ $(($(date +\%s) / 60 \% 7 )) -eq 0 ] && ( command )
    第 2 条附言  ·  51 天前
    根据#138 的提示。穷举法可以进一步缩写为:
    #周一
    0/7 0/7 * * 1 command
    3/7 1/7 * * 1 command
    6/7 2/7 * * 1 command
    2/7 3/7 * * 1 command
    5/7 4/7 * * 1 command
    1/7 5/7 * * 1 command
    4/7 6/7 * * 1 command
    #周二
    2/7 0/7 * * 2 command
    5/7 1/7 * * 2 command
    1/7 2/7 * * 2 command
    4/7 3/7 * * 2 command
    0/7 4/7 * * 2 command
    3/7 5/7 * * 2 command
    6/7 6/7 * * 2 command
    #周三
    4/7 0/7 * * 3 command
    0/7 1/7 * * 3 command
    3/7 2/7 * * 3 command
    6/7 3/7 * * 3 command
    2/7 4/7 * * 3 command
    5/7 5/7 * * 3 command
    1/7 6/7 * * 3 command
    #周四
    6/7 0/7 * * 4 command
    2/7 1/7 * * 4 command
    5/7 2/7 * * 4 command
    1/7 3/7 * * 4 command
    4/7 4/7 * * 4 command
    0/7 5/7 * * 4 command
    3/7 6/7 * * 4 command
    #周五
    1/7 0/7 * * 5 command
    4/7 1/7 * * 5 command
    0/7 2/7 * * 5 command
    3/7 3/7 * * 5 command
    6/7 4/7 * * 5 command
    2/7 5/7 * * 5 command
    5/7 6/7 * * 5 command
    #周六
    3/7 0/7 * * 6 command
    6/7 1/7 * * 6 command
    2/7 2/7 * * 6 command
    5/7 3/7 * * 6 command
    1/7 4/7 * * 6 command
    4/7 5/7 * * 6 command
    0/7 6/7 * * 6 command
    #周日
    5/7 0/7 * * 7 command
    1/7 1/7 * * 7 command
    4/7 2/7 * * 7 command
    0/7 3/7 * * 7 command
    3/7 4/7 * * 7 command
    6/7 5/7 * * 7 command
    2/7 6/7 * * 7 command
    162 条回复    2024-06-03 17:29:59 +08:00
    1  2  
    tmtstudio
        1
    tmtstudio  
       53 天前
    */7 * * * * test.sh
    oneisall8955
        2
    oneisall8955  
       53 天前
    每隔 7 分钟执行一次?

    https://crontab.guru/#*/7_*_*_*_*
    superrichman
        3
    superrichman  
       53 天前   ❤️ 5
    60 不能被 7 整除,单纯用 cron 是不行的
    FranzKafka95
        4
    FranzKafka95  
       53 天前 via Android
    @superrichman 为什么要考虑 60 被 7 整除,op 的需求只是间隔 7 分钟
    xzh920126
        5
    xzh920126  
       53 天前   ❤️ 6
    cron 每分钟执行一次 sh ,在 sh 里判断时间
    timnottom
        6
    timnottom  
       53 天前
    这个我知道,用两个 cron 表达式执行同一个命令
    Puteulanus
        7
    Puteulanus  
       53 天前   ❤️ 3
    用 7 条 cron 把一个 420 分钟循环内落在每个小时里的分钟数都给写上,应该可以
    wuyadaxian
        8
    wuyadaxian  
    OP
       53 天前
    @xzh920126 sh 不能修改。实际上可能是我不能控制的已经封装好的程序。这里只是讨论单纯用 crontab 内能不能实现。用 sh 就很方便了。
    ugpu
        9
    ugpu  
       53 天前
    */7 * * * * /path/to/test.sh
    abelyao
        10
    abelyao  
       53 天前
    @tmtstudio
    @oneisall8955
    @FranzKafka95
    @xzh920126

    cron 不行吧?*/7 * * * * 的话,在 17:56 会执行一次,在 18:00 又会执行一次了
    xzh920126
        11
    xzh920126  
       53 天前   ❤️ 1
    @wuyadaxian 可以把执行时间写入一个文件缓存,cron 每分钟调用 t1.sht1.sh 里读取缓存做时间判断,再调用 test.sh
    superrichman
        12
    superrichman  
       53 天前   ❤️ 4
    @FranzKafka95 因为 cron 表达式 */7 只会在能被 7 整除的时候执行,举例来说 17:56 和 18:00 的时候都会执行,这可不是每 7 分钟运行一次的意思。
    dapang1221
        13
    dapang1221  
       53 天前
    */7 * * * * date >> /var/root/test.log

    加上了,半小时后我过来回复到底能不能用
    xzh920126
        14
    xzh920126  
       53 天前
    @wuyadaxian 明白你的意思了,等大佬解惑~
    bthulu
        15
    bthulu  
       53 天前
    别用 cron, 不稳定, 不定什么时候就漏执行了
    wuyadaxian
        16
    wuyadaxian  
    OP
       53 天前
    @xzh920126 都上 sh ,不如直接 sh 内调用,然后 sleep 420 。循环就好。所以只是在讨论。实际用其他脚本语言会更快。
    Moyyyyyyyyyyye
        17
    Moyyyyyyyyyyye  
       53 天前
    整个公倍数,每分钟都列出来
    ChengLuffy
        18
    ChengLuffy  
       53 天前   ❤️ 1
    @wuyadaxian cron 每分钟 -> bash 脚本判断 -> 目标程序执行
    1462326016
        19
    1462326016  
       53 天前
    如果解决不了问题那么就加一层
    这里假设楼上所说的不能被 60 整除的问题存在且不能单纯的使用 */7 * * * * /path/to/test.sh 这种方式来解决问题
    可以再写一个脚本来调用 test.sh ,在那个脚本里面可以任意判断了。
    lithiumii
        20
    lithiumii  
       53 天前 via Android
    cron 写每分钟运行,命令先判断当前时间是否整除然后再运行,bash 的各种离谱写法应该可以实现
    hahahahahahahah
        21
    hahahahahahahah  
       53 天前
    crontab 没法实现
    Puteulanus
        22
    Puteulanus  
       53 天前   ❤️ 5
    wuyadaxian
        23
    wuyadaxian  
    OP
       53 天前
    @Puteulanus 换天的时候会混乱。按照上面代码,第一天 23:48,23:55 分执行,第二天 00:00,00:07 执行.-------实际第二天应该 00:02,00:09 执行
    carity
        24
    carity  
       53 天前
    五楼方案不是挺好的吗
    Puteulanus
        25
    Puteulanus  
       53 天前
    @wuyadaxian 确实,忘了考虑这点 😂
    wuyadaxian
        26
    wuyadaxian  
    OP
       53 天前   ❤️ 1
    @Puteulanus 穷举法其实我想过,前面 4 位,分/小时/天/月,每次进位都会出现问题。因为 60 分/24 小时/28 天 or29 天 or30 天 or31 天/12 月 ,以上数字均不能被 7 整除形成循环。全部穷举后如果每年都是 365 天,7 年可以循环一次。但是实际上每 4 年有一次有闰年,也就是每 28 年才能穷举一次所有时间。
    busier
        27
    busier  
       53 天前   ❤️ 2
    @wuyadaxian "都上 sh ,不如直接 sh 内调用,然后 sleep 420 。循环就好。所以只是在讨论。实际用其他脚本语言会更快。"

    不可靠!脚本运行命令以及等待命令返回都是要消耗时间的,并且这个时间还不确定。

    你可以每 sleep 420 将系统 RTC 时间写一下 log ,累积起来时间偏差会越来越大!

    所以应该通过不断(例如每 0.2s)读取 UNIX 时间戳方式判断是否经过了 7 秒。而不能去 sleep 7 秒。
    wuyadaxian
        28
    wuyadaxian  
    OP
       53 天前
    @busier 感谢提醒,收到。确实 sleep 是在调用之后,会累计增加前面一句调用时间。
    wudanyang
        29
    wudanyang  
       53 天前
    用 at 命令
    每次在脚本执行的时候先执行一下 at 命令

    ```
    echo "/path/to/myscript.sh" | at now + 7 minutes

    你的逻辑
    ```
    busier
        30
    busier  
       53 天前
    @wuyadaxian 你前面的,涉及时间计算的问题统一用 UNIX 时间戳进行。彻底解决各种烦恼!
    emor
        31
    emor  
       53 天前
    用 5 楼的方式,每分钟扫描一次,获取时间戳,t = 时间戳毫秒/11000/60 ,再用对 t 对 7 取余
    wuyadaxian
        32
    wuyadaxian  
    OP
       53 天前   ❤️ 1
    @Puteulanus 等等,我发现一周可以被 7 整除,而且一周这个单位不会被前面 4 个所影响。所以使用最后一个周作为标记来进行穷举即可。
    snipking
        33
    snipking  
       53 天前   ❤️ 2
    @wuyadaxian 不是还有星期这一位吗?考虑到跨天,写 49 条也能穷举了
    wuyadaxian
        34
    wuyadaxian  
    OP
       53 天前   ❤️ 1
    @Puteulanus 我们只需要每天穷举 7 条 cron ,每周 7 天穷举 49 条 cron 就能实现。如果需要增加偏移量,只需要更改周的位置即可。
    skyrim61
        35
    skyrim61  
       53 天前
    @dapang1221 半个小时过去了
    suyuyu
        36
    suyuyu  
       53 天前
    @dapang1221 38 分钟了怎么说
    wps353
        37
    wps353  
       53 天前
    systemd.timer 应该可以
    mohumohu
        38
    mohumohu  
       53 天前
    #!/bin/sh

    start_time=$(date +%s)

    while true; do
    current_time=$(date +%s)

    elapsed_time=$((current_time - start_time))

    if [ $elapsed_time -ge 420 ]; then
    ./myscript.sh

    start_time=$(date +%s)
    fi

    sleep 1
    done
    mohumohu
        39
    mohumohu  
       53 天前
    * * * * * ( [ -f /tmp/timestamp ] || date +\%s > /tmp/timestamp ) && [ $(( $(date +\%s) - $(cat /tmp/timestamp) )) -ge 420 ] && ( ./myscript.sh && date +\%s > /tmp/timestamp )
    wuyadaxian
        40
    wuyadaxian  
    OP
       53 天前
    @mohumohu 后面 command 部分能接这种复杂的命令集吗?我尝试了下 cron 没运行(不知道是不是我的问题),但是直接输入后面的 command 是可以运行的。
    mohumohu
        41
    mohumohu  
       53 天前
    @wuyadaxian 写绝对路径试试,/bin/date
    pckillers
        42
    pckillers  
       53 天前   ❤️ 4
    cron 每分钟执行一次 sh 。 sh 里每次都判断特定文件夹里有几个文件。有 6 个文件时清空文件夹并执行实际代码。 不满 6 个文件时把当前 timestamp 作为文件名创建文件,不执行代码。

    这样就能 7 分钟一次了
    Richared
        43
    Richared  
       53 天前
    定时每分钟执行,脚本里判断次数不就完了么。
    lolizeppelin
        44
    lolizeppelin  
       53 天前   ❤️ 1
    先说清楚,间隔从执行开始算起还是执行后算起

    执行前算起的话,脚本执行超过 7 分钟如何处理
    wuyadaxian
        45
    wuyadaxian  
    OP
       53 天前
    @mohumohu 我尝试 * * * * * ((($(date +%s) / 60 % 7 == 0)) && /etc/test.sh) 并 [没有运行] 。我已经确认用户拥有 test.sh 的读写运行权限。另外我直接在 tty 里面输入((($(date +%s) / 60 % 7 == 0)) && /etc/test.sh)是 [可以运行] 的。
    wuyadaxian
        46
    wuyadaxian  
    OP
       53 天前
    @lolizeppelin 每隔 7 分钟,执行一次 test 脚本,不管 test 脚本之后的状态。
    lolizeppelin
        47
    lolizeppelin  
       53 天前
    Ubuntu 22.04 不是有 systemd 么,
    timer

    OnUnitActiveSec 搞定,用啥 cron
    lrh3321
        48
    lrh3321  
       53 天前
    该切到 systemd 的 timer 上了
    yankebupt
        49
    yankebupt  
       53 天前
    如楼主回复所言,day of the week 可以被 7 整除,所以穷举一下是可以的,可能也就一千多条吧,换上用 slash(/)的 initial value 优化下也有几百条,真的合适么……
    wuyadaxian
        50
    wuyadaxian  
    OP
       53 天前
    @yankebupt 见 33 ,34 楼,只需要 49 条,还可以设置偏移量。
    wuyadaxian
        51
    wuyadaxian  
    OP
       53 天前
    @mohumohu 我找到一篇文章,https://href.lu/15A 。此文章表示在 macOS 中成功使用了复杂的 command 。但是我在我现在的 linux ubuntu 下没有运行成功。不知道是不是哪里错了,比如需要用引号之类的。
    brant2ai
        52
    brant2ai  
       53 天前
    从每个小时的角度,每隔 7 分钟,就有 7 种开始时间。所以可以在每个小时开始时判断开始判断是那种,然后复写调度。
    yinxs2003
        53
    yinxs2003  
       53 天前 via Android
    */7

    对吗,我猜的
    brant2ai
        54
    brant2ai  
       53 天前
    @brant2ai 比如 0 分钟开始,调度就是 0 ,07 ,14 ,21 ,28 ,35 ,42 ,49 ,56 ,以及下个小时的 03 。在 63 的时间点,判断是不是个位,如果是,则继续加到下一个小时,并覆盖 crontab
    killva4624
        55
    killva4624  
       53 天前
    每 7 分钟一次,不能能用简单整除的方法,我想到的:
    - 要么就穷举一次循环,把循环分钟记录下来作为判断;
    - 要么就每次执行完写一次时间到文件,下次运行的时候从这个文件判断要不要是不是已间隔 7 分钟。
    xuanbg
        56
    xuanbg  
       53 天前
    cron 做不到,脚本内循环判断时间戳/60 后对 7 取余是否为 0 即可。但你要保证每次执行业务逻辑都能在 7 分钟内完成才行。
    wuyadaxian
        57
    wuyadaxian  
    OP
       53 天前
    @brant2ai 复写的时候是哪段代码或什么外部程序或者谁(真人)来进行。
    brant2ai
        58
    brant2ai  
       53 天前
    @wuyadaxian #57 你可以写到/etc/crontab 里,每次删除最后一条再把新的插入进去
    brant2ai
        59
    brant2ai  
       53 天前
    @wuyadaxian #57 就是你自己的这个脚本本身需要有权限去写。开权限就可以了
    RedisMasterNode
        60
    RedisMasterNode  
       53 天前
    @xzh920126
    > cron 每分钟执行一次 sh ,在 sh 里判断时间
    就算能修改 sh 好像也不行呀,看上下文基本可以确认是个无状态的任务(那就假设它是吧),sh 里怎么知道上次执行是啥时候,隔了多久咧
    wuyadaxian
        61
    wuyadaxian  
    OP
       53 天前
    @brant2ai 要操作外部脚本啊,那就不在讨论范围了。都能用外部脚本了,方法就多了,楼上很多。
    dapang1221
        62
    dapang1221  
       53 天前   ❤️ 4
    Thu May 30 17:07:00 CST 2024
    Thu May 30 17:14:00 CST 2024
    Thu May 30 17:21:00 CST 2024
    Thu May 30 17:28:00 CST 2024
    Thu May 30 17:35:00 CST 2024
    Thu May 30 17:42:00 CST 2024
    Thu May 30 17:49:01 CST 2024
    Thu May 30 17:56:00 CST 2024
    Thu May 30 18:00:00 CST 2024
    Thu May 30 18:07:00 CST 2024
    Thu May 30 18:14:00 CST 2024
    Thu May 30 18:21:00 CST 2024
    Thu May 30 18:28:00 CST 2024
    Thu May 30 18:35:00 CST 2024
    Thu May 30 18:42:00 CST 2024

    实测只用 */7 * * * * 确实不行 - - @skyrim61 @suyuyu
    foursking
        63
    foursking  
       53 天前
    */7 不行,如果一定要实现间隔,貌似只能 外部引入一个 sleep_7_minutes.sh 实现
    brant2ai
        64
    brant2ai  
       53 天前
    @wuyadaxian #61
    $schedule->command('b2buhrenApi:productSync')
    ->when(intval(time()/60) % 7 ==0);
    这个是老外的回答,你试试
    https://laracasts.com/discuss/channels/laravel/how-to-run-schedule-every-7-minutes?page=1&replyId=821790
    RRRoger
        65
    RRRoger  
       53 天前
    最小公倍数原理
    brant2ai
        66
    brant2ai  
       53 天前
    @wuyadaxian #61 又找了一个
    [[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] &&
    wuyadaxian
        67
    wuyadaxian  
    OP
       53 天前
    @brant2ai 我试试
    brant2ai
        68
    brant2ai  
       53 天前
    @wuyadaxian #61 * * * * * [[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] && command 前面的这个并上你的命令,每分钟做判断,如果是就执行
    aa51513
        69
    aa51513  
       53 天前 via Android
    @RedisMasterNode 写文件,把上次运行的时间写到文件里,我看很多程序就把自身运行的 pid 写到文件里,很常规的操作吧
    wuyadaxian
        70
    wuyadaxian  
    OP
       53 天前
    @brant2ai bash: syntax error near unexpected token `(' 是我的环境问题吗
    wuyadaxian
        71
    wuyadaxian  
    OP
       53 天前
    @brant2ai 你可以看看 45 楼和 51 楼,我不确定是不是我环境或者什么问题,在 ubuntu 下无法执行。
    brant2ai
        72
    brant2ai  
       53 天前
    @wuyadaxian #70 减掉一层括号试试
    wuyadaxian
        73
    wuyadaxian  
    OP
       53 天前
    @brant2ai 另外这个算没用 cron 了吧。
    RedisMasterNode
        74
    RedisMasterNode  
       53 天前
    @aa51513 要能这么玩我估计不会有本帖 hhh
    vipfts
        75
    vipfts  
       53 天前
    @wuyadaxian #34 学到了
    mohumohu
        76
    mohumohu  
       53 天前
    * * * * * source /etc/profile && ( [ -f /tmp/timestamp ] || date +\%s > /tmp/timestamp ) && [ $(( $(date +\%s) - $(cat /tmp/timestamp) )) -ge 10 ] && ( echo 2 && date +\%s > /tmp/timestamp )
    brant2ai
        77
    brant2ai  
       53 天前
    @wuyadaxian #73
    @wuyadaxian #70 我在服务器上测试是可以的
    [[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] && echo hello 。另外这个是目前最简单的不用引用外部的做法
    wuyadaxian
        78
    wuyadaxian  
    OP
       53 天前
    @brant2ai 同样,在 cron 里面* * * * * [[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] && command 。 [无法运行] ------在 tty 内,[[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] && command 。 [正常运行]
    wuyadaxian
        79
    wuyadaxian  
    OP
       53 天前
    @brant2ai 我也可以直接在 tty 中使用这行 command ,但是 cron 里面不会运行
    brant2ai
        80
    brant2ai  
       53 天前
    @wuyadaxian #79 你检查下 crontab 是不是写对的
    wuyadaxian
        81
    wuyadaxian  
    OP
       53 天前
    * * * * * [[ $(($(date +'%s / 60 % 1 '))) -eq 0 ]] && /etc/test.sh
    我将%7 改为%1 ,这样理论上每分钟就会运行一次 test.sh 。但是没有运行
    wuyadaxian
        82
    wuyadaxian  
    OP
       53 天前
    @brant2ai 见楼上,我已经正确赋予了用户对 test.sh 的读写运行权限。
    另外如果我改为* * * * * /etc/test.sh 是可以正常每分钟运行的。
    wuyadaxian
        83
    wuyadaxian  
    OP
       53 天前
    @brant2ai 同时,直接在窗口运行 [[ $(($(date +'%s / 60 % 1 '))) -eq 0 ]] && /etc/test.sh
    是没问题的,因为左边部分永远为真,右边始终会执行。
    lovelylain
        84
    lovelylain  
       53 天前
    @wuyadaxian 那就写到脚本里面呗,每分钟执行 1 次脚本,脚本里[[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] || exit
    wuyadaxian
        85
    wuyadaxian  
    OP
       53 天前
    @brant2ai 如果你那边服务器可以运行,请告诉我以下你服务器的系统和版本号。我去装一个测试下,看是不是只有 ubuntu 不行。
    maladaxia
        86
    maladaxia  
       53 天前
    yangxiaopeipei
        87
    yangxiaopeipei  
       53 天前
    执行完 sleep 7*60
    brant2ai
        88
    brant2ai  
       53 天前
    @wuyadaxian #83 我也试试,crontab 好像是不太行,我改了几次命令,好像还是执行不了
    director
        89
    director  
       53 天前
    每分钟跑一次,在程序里判断时间点/7 的余数为某个值就执行
    momomirage
        90
    momomirage  
       53 天前
    一周有 7 天

    所以用多(但是有限)个 cron 表达式合起来应该可以每 7 分钟一次
    wuyadaxian
        91
    wuyadaxian  
    OP
       53 天前
    @brant2ai #88 估计和平台有关 。
    #51 楼我找到一个文章,声称使用 macOS 可以这么运行。
    但是没有发现 linux 平台下的案例。
    zzhaolei
        92
    zzhaolei  
       53 天前
    不会是面试题吧?要么加一层,然后写入上次执行的时间,如果也不能写文件,那就放弃吧,纯 crontab 肯定实现不了
    feedcode
        93
    feedcode  
       53 天前   ❤️ 2
    换个思路
    systemd-run --on-boot=30 --on-unit-active=420 bash /path/script.sh

    Running timer as unit: run-r2f2f454d18944d79af858a4be4f48cd5.timer
    Will run service as unit: run-r2f2f454d18944d79af858a4be4f48cd5.service

    如果测试 ok,把对应的 timer 和 service 从/run/systemd/transient/ move 到/etc/systemd/system 做持久化
    Ipsum
        94
    Ipsum  
       53 天前
    最简单就是每分钟运行,然后脚本获取当前时间,分钟能被 7 整除就运行。否则就退出。如果是其他时间 60 能被 n 整除可以用*/n
    dxdydz
        95
    dxdydz  
       53 天前 via iPhone
    我想了个双脚本思路,大致内容如下
    script_a.sh:
    #!/bin/bash
    # 使用 at 命令在 7 分钟后执行脚本 b
    #run task
    echo "/path/to/script_b.sh" | at now + 7 minutes
    script_b.sh:
    #!/bin/bash
    # 使用 at 命令在 7 分钟后执行脚本 a
    #run task
    echo "/path/to/script_a.sh" | at now + 7 minutes
    noyle
        96
    noyle  
       53 天前   ❤️ 4
    @wuyadaxian

    `[[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] &&`
    这句在 cron 里有几个问题:
    1 ,`[[`是 bash 扩展,不是命令,所以在 cron 的 shell 环境里报错,改用`[ ... ]`或者`test ...`应该就没问题了。[1]
    2 ,字面`%`在 cron 里应该用`\`转义。[2]

    所以,下面这条应该可以:
    `*/1 * * * * root [ $(($(date +'\%s / 60 \% 7 '))) -eq 0 ] && ( echo "CRON RUN" | logger )`

    [1] https://stackoverflow.com/a/47576482/6681141
    [2] https://serverfault.com/questions/274475/escaping-double-quotes-and-percent-signs-in-cron
    ramirezyolis808
        97
    ramirezyolis808  
       52 天前 via iPhone
    写复杂命令在 cron 里面可以实现,但是这个和套一层 shell 有啥本质区别?无非是把外层的判断写在了 cron 行上面了而已
    james122333
        98
    james122333  
       52 天前 via Android
    直接写 bash 脚本 cron 本来就是用在规律用途 也比较鸡肋 因为 bash 本身就能实现 cron 的功能
    有准确的用法 至于 sleep 为何会不准因为是外部命令 启动要时间 用久会有大误差 这需求有不只一种实现方法
    systemd? 垃圾东西就不要用了
    hackerwgf
        99
    hackerwgf  
       52 天前
    哎,就喜欢这样的 v2
    asche910
        100
    asche910  
       52 天前
    用脚本吧,sleep ( 7 * 60 ),然后异步执行
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1054 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 19:20 · PVG 03:20 · LAX 12:20 · JFK 15:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.