• 请不要在回答技术问题时复制粘贴 AI 生成的内容
wuyadaxian
V2EX  ›  程序员

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

  •  4
     
  •   wuyadaxian · May 30, 2024 · 22507 views
    This topic created in 887 days ago, the information mentioned may be changed or developed.
    我的环境是 Ubuntu 22.04LTS 。
    要求是从现在或者某个时间点开始,每 7 分钟执行一次 test.sh 脚本。
    只能使用 crontab 来编写。
    只是讨论,真正实现的时候肯定用 bash 或者其他语言脚本更方便实现。
    Supplement 1  ·  Jun 1, 2024
    -------------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 )
    Supplement 2  ·  Jun 1, 2024
    根据#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 replies  •  2024-06-03 17:29:59 +08:00
    1  2  
    ❮ ❯
    tmtstudio
    tmtstudio
    May 30, 2024
    1
    */7 * * * * test.sh
    itechify
    itechify
    May 30, 2024
    2
    每隔 7 分钟执行一次?

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

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

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

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

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

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

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

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

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

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

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

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

    所以用多(但是有限)个 cron 表达式合起来应该可以每 7 分钟一次
    wuyadaxian
    wuyadaxian
    OP
    May 30, 2024
    91
    @brant2ai #88 估计和平台有关 。
    #51 楼我找到一个文章,声称使用 macOS 可以这么运行。
    但是没有发现 linux 平台下的案例。
    zzhaolei
    zzhaolei
    May 30, 2024
    92
    不会是面试题吧?要么加一层,然后写入上次执行的时间,如果也不能写文件,那就放弃吧,纯 crontab 肯定实现不了
    feedcode
    feedcode
    May 30, 2024❤️2
    93
    换个思路
    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
    Ipsum
    May 30, 2024
    94
    最简单就是每分钟运行,然后脚本获取当前时间,分钟能被 7 整除就运行。否则就退出。如果是其他时间 60 能被 n 整除可以用*/n
    dxdydz
    dxdydz
    May 30, 2024 via iPhone
    95
    我想了个双脚本思路,大致内容如下
    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
    noyle
    May 31, 2024❤️4
    96
    @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
    ZeekChatCom
    May 31, 2024 via iPhone
    97
    写复杂命令在 cron 里面可以实现,但是这个和套一层 shell 有啥本质区别?无非是把外层的判断写在了 cron 行上面了而已
    james122333
    james122333
    May 31, 2024 via Android
    98
    直接写 bash 脚本 cron 本来就是用在规律用途 也比较鸡肋 因为 bash 本身就能实现 cron 的功能
    有准确的用法 至于 sleep 为何会不准因为是外部命令 启动要时间 用久会有大误差 这需求有不只一种实现方法
    systemd? 垃圾东西就不要用了
    hackerwgf
    hackerwgf
    May 31, 2024
    99
    哎,就喜欢这样的 v2
    asche910
    asche910
    May 31, 2024
    100
    用脚本吧,sleep ( 7 * 60 ),然后异步执行
    1  2  
    ❮ ❯
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5032 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 173ms · UTC 07:39 · PVG 15:39 · LAX 23:39 · JFK 02:39
    ♥ Do have faith in what you're doing.