【问题标题】:In bash/ash how to construct logic for checking cron?在 bash/ash 中如何构造检查 cron 的逻辑?
【发布时间】:2021-01-22 01:51:44
【问题描述】:

我正在尝试创建一个脚本来比较 cron,如果当前日期/时间在 cron 开始/停止时间之内,则执行一个函数。如果启动/停止只有一个 cron 条目,这将很简单,但我不知道如何允许多个 cron。我正在使用 posix/ash 但如果有人可以提供一个 bash 示例,希望我能适应它。我只是不明白如何构建逻辑?

例如:如果 cron 是这样,那将是一个简单的if 语句:

00 09 * * Mon,Tue,Wed,Thu,Fri,Sat,Sun /usr/bin/wifi_schedule.sh start
00 11 * * Mon,Tue,Wed,Thu,Fri,Sat,Sun /usr/bin/wifi_schedule.sh stop

但是如果有多个 crons,我不确定如何处理:

00 09 * * Mon,Tue,Wed,Thu,Fri,Sat,Sun /usr/bin/wifi_schedule.sh start
00 11 * * Mon,Tue,Wed,Thu,Fri,Sat,Sun /usr/bin/wifi_schedule.sh stop
00 15 * * Mon,Tue,Wed,Thu,Fri,Sat,Sun /usr/bin/wifi_schedule.sh start
00 17 * * Mon,Tue,Wed,Thu,Fri,Sat,Sun /usr/bin/wifi_schedule.sh stop
00 19 * * Mon,Tue,Wed,Thu,Fri,Sat,Sun /usr/bin/wifi_schedule.sh start
00 21 * * Mon,Tue,Wed,Thu,Fri,Sat,Sun /usr/bin/wifi_schedule.sh stop

我尝试过使用while,但这似乎只对第一个匹配项起作用或进入循环。

如果它与 cron 匹配,我正在尝试做的是调用启动无线功能。例如,如果设备在 cron 启动时间之后和 cron 停止时间之前启动,则启动无线,或者如果它在 cron 停止之后启动,则停止无线。到目前为止我尝试过的一些事情是:

获取当前的$day$hour

day=$(date +%a) & hour=$(date +%H)

$day 获取 cron $start$stop 时间

start=$(grep $day /etc/crontabs/root | awk '/start/ {print $2}')
stop=$(grep $day /etc/crontabs/root | awk '/stop/ {print $2}')

计算发生了多少次开始/停止时间(例如$count=3

count=$(echo "$start" | wc -l)

为启动/停止创建变量

set -- $start
set -- $stop

$count=3 确定变量(例如 -- $3$2$1

var=$(eval echo \$$count)

我使用while的失败示例:

while [ $var -le $hour ];
  do
    if [ $hour -ge $var ]; then
      echo "do something"
    else
      var=$(eval echo \$$count)
      count=$(( $count - 1 ))
      echo "do something else"
    fi
  done
exit

任何有关这方面的指导将不胜感激,谢谢。

【问题讨论】:

    标签: bash logic sh posix ash


    【解决方案1】:

    解析 crontabs 以确定是否应该运行作业在我看来根本是错误的。 如果有 另一个 crontab 运行相同的脚本集怎么办? 如果脚本是手动运行的呢? 如果将 cron-logic 切换为 systemd.timers 会怎样?

    看来您真正想做的是检查系统是否处于给定状态(例如“WiFi已打开”甚至“WiFi应该打开”)。

    所以你真正应该做的是尝试找出系统是否处于请求状态。

    这可以像在 cron 执行的脚本中设置一个标志一样简单。

    例如你的 wifi_schedule.sh 脚本(你真的应该把它放入 /usr/local/bin/ ,因为 /usr/bin 是为系统保留的):

    #!/bin/sh
    case "$1" in
      start)
         echo 1 > /var/run/wifi_schedule
         ;;
      stop)
         echo 0 > /var/run/wifi_schedule
         ;;
    esac
    
    # here comes the actual script:
    # ...
    

    如果手头的实际任务更复杂,您可以考虑从cron 切换到systemd.unit(显然只有在您可以接受systemd 的情况下),这可以让您表达时间,执行顺序及其各部分之间的依赖关系。

    【讨论】:

    • 它来自插件 luci-app-wifischedule 生成的 OpenWrt cron 条目。我明白你关于 cron 的观点,所以我也可以 grep/awk 来自 luci-app-wifischedule 配置文件的相同数据,但它将是设备上唯一的 cron 功能。系统配置为禁用 wifi,这就是为什么我希望脚本检查它是否错过了预定的开始时间。我不想修改 luci-app-wifischedule 脚本。感谢您的贡献:)
    • @Brenton 我对此了解不多,但您链接的页面末尾的 README 列出了一些可能使您更轻松的内容:/usr/bin/wifi_schedule.sh recheck
    • 感谢@MemReflect 很好发现,但不只检查是否有关联的电台它不会stop 无线除非你使用forecestop 命令
    猜你喜欢
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 2016-12-28
    相关资源
    最近更新 更多