V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
wuyadaxian
V2EX  ›  程序员

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

  •  4
     
  •   wuyadaxian · 2024-05-30 16:47:00 +08:00 · 17697 次点击
    这是一个创建于 382 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我的环境是 Ubuntu 22.04LTS 。
    要求是从现在或者某个时间点开始,每 7 分钟执行一次 test.sh 脚本。
    只能使用 crontab 来编写。
    只是讨论,真正实现的时候肯定用 bash 或者其他语言脚本更方便实现。
    第 1 条附言  ·  2024-06-01 12:12:52 +08:00
    -------------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 条附言  ·  2024-06-01 12:26:30 +08:00
    根据#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  
       2024-05-30 16:54:27 +08:00
    */7 * * * * test.sh
    oneisall8955
        2
    oneisall8955  
       2024-05-30 16:55:06 +08:00
    每隔 7 分钟执行一次?

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

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

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

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

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

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

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

    你的逻辑
    ```
    busier
        30
    busier  
       2024-05-30 17:38:42 +08:00
    @wuyadaxian 你前面的,涉及时间计算的问题统一用 UNIX 时间戳进行。彻底解决各种烦恼!
    emor
        31
    emor  
       2024-05-30 17:40:27 +08:00
    用 5 楼的方式,每分钟扫描一次,获取时间戳,t = 时间戳毫秒/11000/60 ,再用对 t 对 7 取余
    wuyadaxian
        32
    wuyadaxian  
    OP
       2024-05-30 17:42:21 +08:00   ❤️ 1
    @Puteulanus 等等,我发现一周可以被 7 整除,而且一周这个单位不会被前面 4 个所影响。所以使用最后一个周作为标记来进行穷举即可。
    snipking
        33
    snipking  
       2024-05-30 17:42:57 +08:00   ❤️ 2
    @wuyadaxian 不是还有星期这一位吗?考虑到跨天,写 49 条也能穷举了
    wuyadaxian
        34
    wuyadaxian  
    OP
       2024-05-30 17:44:22 +08:00   ❤️ 1
    @Puteulanus 我们只需要每天穷举 7 条 cron ,每周 7 天穷举 49 条 cron 就能实现。如果需要增加偏移量,只需要更改周的位置即可。
    skyrim61
        35
    skyrim61  
       2024-05-30 17:44:42 +08:00
    @dapang1221 半个小时过去了
    suyuyu
        36
    suyuyu  
       2024-05-30 17:45:01 +08:00
    @dapang1221 38 分钟了怎么说
    wps353
        37
    wps353  
       2024-05-30 17:45:46 +08:00
    systemd.timer 应该可以
    mohumohu
        38
    mohumohu  
       2024-05-30 17:49:01 +08:00
    #!/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  
       2024-05-30 17:51:17 +08:00
    * * * * * ( [ -f /tmp/timestamp ] || date +\%s > /tmp/timestamp ) && [ $(( $(date +\%s) - $(cat /tmp/timestamp) )) -ge 420 ] && ( ./myscript.sh && date +\%s > /tmp/timestamp )
    wuyadaxian
        40
    wuyadaxian  
    OP
       2024-05-30 17:53:34 +08:00
    @mohumohu 后面 command 部分能接这种复杂的命令集吗?我尝试了下 cron 没运行(不知道是不是我的问题),但是直接输入后面的 command 是可以运行的。
    mohumohu
        41
    mohumohu  
       2024-05-30 17:58:31 +08:00
    @wuyadaxian 写绝对路径试试,/bin/date
    pckillers
        42
    pckillers  
       2024-05-30 18:00:07 +08:00   ❤️ 4
    cron 每分钟执行一次 sh 。 sh 里每次都判断特定文件夹里有几个文件。有 6 个文件时清空文件夹并执行实际代码。 不满 6 个文件时把当前 timestamp 作为文件名创建文件,不执行代码。

    这样就能 7 分钟一次了
    Richared
        43
    Richared  
       2024-05-30 18:00:52 +08:00
    定时每分钟执行,脚本里判断次数不就完了么。
    lolizeppelin
        44
    lolizeppelin  
       2024-05-30 18:02:32 +08:00   ❤️ 1
    先说清楚,间隔从执行开始算起还是执行后算起

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

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

    对吗,我猜的
    brant2ai
        54
    brant2ai  
       2024-05-30 18:34:39 +08:00
    @brant2ai 比如 0 分钟开始,调度就是 0 ,07 ,14 ,21 ,28 ,35 ,42 ,49 ,56 ,以及下个小时的 03 。在 63 的时间点,判断是不是个位,如果是,则继续加到下一个小时,并覆盖 crontab
    killva4624
        55
    killva4624  
       2024-05-30 18:38:10 +08:00
    每 7 分钟一次,不能能用简单整除的方法,我想到的:
    - 要么就穷举一次循环,把循环分钟记录下来作为判断;
    - 要么就每次执行完写一次时间到文件,下次运行的时候从这个文件判断要不要是不是已间隔 7 分钟。
    xuanbg
        56
    xuanbg  
       2024-05-30 18:38:15 +08:00
    cron 做不到,脚本内循环判断时间戳/60 后对 7 取余是否为 0 即可。但你要保证每次执行业务逻辑都能在 7 分钟内完成才行。
    wuyadaxian
        57
    wuyadaxian  
    OP
       2024-05-30 18:38:25 +08:00
    @brant2ai 复写的时候是哪段代码或什么外部程序或者谁(真人)来进行。
    brant2ai
        58
    brant2ai  
       2024-05-30 18:41:37 +08:00
    @wuyadaxian #57 你可以写到/etc/crontab 里,每次删除最后一条再把新的插入进去
    brant2ai
        59
    brant2ai  
       2024-05-30 18:42:23 +08:00
    @wuyadaxian #57 就是你自己的这个脚本本身需要有权限去写。开权限就可以了
    RedisMasterNode
        60
    RedisMasterNode  
       2024-05-30 18:43:13 +08:00
    @xzh920126
    > cron 每分钟执行一次 sh ,在 sh 里判断时间
    就算能修改 sh 好像也不行呀,看上下文基本可以确认是个无状态的任务(那就假设它是吧),sh 里怎么知道上次执行是啥时候,隔了多久咧
    wuyadaxian
        61
    wuyadaxian  
    OP
       2024-05-30 18:44:32 +08:00
    @brant2ai 要操作外部脚本啊,那就不在讨论范围了。都能用外部脚本了,方法就多了,楼上很多。
    dapang1221
        62
    dapang1221  
       2024-05-30 18:44:34 +08:00   ❤️ 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  
       2024-05-30 18:56:28 +08:00
    */7 不行,如果一定要实现间隔,貌似只能 外部引入一个 sleep_7_minutes.sh 实现
    brant2ai
        64
    brant2ai  
       2024-05-30 18:59:12 +08:00
    @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  
       2024-05-30 19:00:06 +08:00
    最小公倍数原理
    brant2ai
        66
    brant2ai  
       2024-05-30 19:03:30 +08:00
    @wuyadaxian #61 又找了一个
    [[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] &&
    wuyadaxian
        67
    wuyadaxian  
    OP
       2024-05-30 19:03:41 +08:00
    @brant2ai 我试试
    brant2ai
        68
    brant2ai  
       2024-05-30 19:05:09 +08:00
    @wuyadaxian #61 * * * * * [[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] && command 前面的这个并上你的命令,每分钟做判断,如果是就执行
    aa51513
        69
    aa51513  
       2024-05-30 19:06:35 +08:00 via Android
    @RedisMasterNode 写文件,把上次运行的时间写到文件里,我看很多程序就把自身运行的 pid 写到文件里,很常规的操作吧
    wuyadaxian
        70
    wuyadaxian  
    OP
       2024-05-30 19:06:37 +08:00
    @brant2ai bash: syntax error near unexpected token `(' 是我的环境问题吗
    wuyadaxian
        71
    wuyadaxian  
    OP
       2024-05-30 19:08:21 +08:00
    @brant2ai 你可以看看 45 楼和 51 楼,我不确定是不是我环境或者什么问题,在 ubuntu 下无法执行。
    brant2ai
        72
    brant2ai  
       2024-05-30 19:09:50 +08:00
    @wuyadaxian #70 减掉一层括号试试
    wuyadaxian
        73
    wuyadaxian  
    OP
       2024-05-30 19:10:29 +08:00
    @brant2ai 另外这个算没用 cron 了吧。
    RedisMasterNode
        74
    RedisMasterNode  
       2024-05-30 19:10:31 +08:00
    @aa51513 要能这么玩我估计不会有本帖 hhh
    vipfts
        75
    vipfts  
       2024-05-30 19:11:16 +08:00
    @wuyadaxian #34 学到了
    mohumohu
        76
    mohumohu  
       2024-05-30 19:14:33 +08:00
    * * * * * 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  
       2024-05-30 19:15:13 +08:00
    @wuyadaxian #73
    @wuyadaxian #70 我在服务器上测试是可以的
    [[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] && echo hello 。另外这个是目前最简单的不用引用外部的做法
    wuyadaxian
        78
    wuyadaxian  
    OP
       2024-05-30 19:16:15 +08:00
    @brant2ai 同样,在 cron 里面* * * * * [[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] && command 。 [无法运行] ------在 tty 内,[[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] && command 。 [正常运行]
    wuyadaxian
        79
    wuyadaxian  
    OP
       2024-05-30 19:17:03 +08:00
    @brant2ai 我也可以直接在 tty 中使用这行 command ,但是 cron 里面不会运行
    brant2ai
        80
    brant2ai  
       2024-05-30 19:23:59 +08:00
    @wuyadaxian #79 你检查下 crontab 是不是写对的
    wuyadaxian
        81
    wuyadaxian  
    OP
       2024-05-30 19:26:33 +08:00
    * * * * * [[ $(($(date +'%s / 60 % 1 '))) -eq 0 ]] && /etc/test.sh
    我将%7 改为%1 ,这样理论上每分钟就会运行一次 test.sh 。但是没有运行
    wuyadaxian
        82
    wuyadaxian  
    OP
       2024-05-30 19:30:51 +08:00
    @brant2ai 见楼上,我已经正确赋予了用户对 test.sh 的读写运行权限。
    另外如果我改为* * * * * /etc/test.sh 是可以正常每分钟运行的。
    wuyadaxian
        83
    wuyadaxian  
    OP
       2024-05-30 19:32:08 +08:00
    @brant2ai 同时,直接在窗口运行 [[ $(($(date +'%s / 60 % 1 '))) -eq 0 ]] && /etc/test.sh
    是没问题的,因为左边部分永远为真,右边始终会执行。
    lovelylain
        84
    lovelylain  
       2024-05-30 19:32:51 +08:00
    @wuyadaxian 那就写到脚本里面呗,每分钟执行 1 次脚本,脚本里[[ $(($(date +'%s / 60 % 7 '))) -eq 0 ]] || exit
    wuyadaxian
        85
    wuyadaxian  
    OP
       2024-05-30 19:38:01 +08:00
    @brant2ai 如果你那边服务器可以运行,请告诉我以下你服务器的系统和版本号。我去装一个测试下,看是不是只有 ubuntu 不行。
    maladaxia
        86
    maladaxia  
       2024-05-30 19:41:51 +08:00
    yangxiaopeipei
        87
    yangxiaopeipei  
       2024-05-30 19:49:29 +08:00
    执行完 sleep 7*60
    brant2ai
        88
    brant2ai  
       2024-05-30 19:54:47 +08:00
    @wuyadaxian #83 我也试试,crontab 好像是不太行,我改了几次命令,好像还是执行不了
    director
        89
    director  
       2024-05-30 19:55:28 +08:00
    每分钟跑一次,在程序里判断时间点/7 的余数为某个值就执行
    momomirage
        90
    momomirage  
       2024-05-30 19:55:55 +08:00
    一周有 7 天

    所以用多(但是有限)个 cron 表达式合起来应该可以每 7 分钟一次
    wuyadaxian
        91
    wuyadaxian  
    OP
       2024-05-30 19:59:07 +08:00
    @brant2ai #88 估计和平台有关 。
    #51 楼我找到一个文章,声称使用 macOS 可以这么运行。
    但是没有发现 linux 平台下的案例。
    zzhaolei
        92
    zzhaolei  
       2024-05-30 20:30:52 +08:00
    不会是面试题吧?要么加一层,然后写入上次执行的时间,如果也不能写文件,那就放弃吧,纯 crontab 肯定实现不了
    feedcode
        93
    feedcode  
       2024-05-30 21:01:29 +08:00   ❤️ 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  
       2024-05-30 22:43:41 +08:00
    最简单就是每分钟运行,然后脚本获取当前时间,分钟能被 7 整除就运行。否则就退出。如果是其他时间 60 能被 n 整除可以用*/n
    dxdydz
        95
    dxdydz  
       2024-05-30 23:25:00 +08:00 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  
       2024-05-31 00:43:16 +08:00   ❤️ 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
    ZeekChatCom
        97
    ZeekChatCom  
       2024-05-31 06:22:50 +08:00 via iPhone
    写复杂命令在 cron 里面可以实现,但是这个和套一层 shell 有啥本质区别?无非是把外层的判断写在了 cron 行上面了而已
    james122333
        98
    james122333  
       2024-05-31 08:56:52 +08:00 via Android
    直接写 bash 脚本 cron 本来就是用在规律用途 也比较鸡肋 因为 bash 本身就能实现 cron 的功能
    有准确的用法 至于 sleep 为何会不准因为是外部命令 启动要时间 用久会有大误差 这需求有不只一种实现方法
    systemd? 垃圾东西就不要用了
    hackerwgf
        99
    hackerwgf  
       2024-05-31 09:14:57 +08:00
    哎,就喜欢这样的 v2
    asche910
        100
    asche910  
       2024-05-31 09:20:03 +08:00
    用脚本吧,sleep ( 7 * 60 ),然后异步执行
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1039 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 22:41 · PVG 06:41 · LAX 15:41 · JFK 18:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.