Bash Shell脚本在一天中运行,以便在特定时间创建文件

Bash Shell脚本在一天中运行,以便在特定时间创建文件,bash,shell,unix,Bash,Shell,Unix,我希望创建一个shell脚本,它将在一天中的特定时间点创建文件 案例。 执行shell脚本后,应在一天中的特定时间在/tmp/work/目录中创建文件 当时间为01:00小时时,应创建abc.txt 当时间为06:00时,应创建def.txt 当时间为13:00时,应创建hij.txt 当时间为23:00时,应创建xyz.txt 所有文件都应包含一些内容,如“这是测试文件。”以使文件大小超过0字节 此时是否可以执行以下操作 echo "THIS IS TEST FILE." > /tmp/

我希望创建一个shell脚本,它将在一天中的特定时间点创建文件

案例。 执行shell脚本后,应在一天中的特定时间在/tmp/work/目录中创建文件

当时间为01:00小时时,应创建abc.txt

当时间为06:00时,应创建def.txt

当时间为13:00时,应创建hij.txt

当时间为23:00时,应创建xyz.txt

所有文件都应包含一些内容,如“这是测试文件。”以使文件大小超过0字节

此时是否可以执行以下操作

echo "THIS IS TEST FILE." > /tmp/work/abc.txt  ## at 01:00 Hrs
echo "THIS IS TEST FILE." > /tmp/work/def.txt  ## at 06:00 Hrs

因此…

在大多数情况下,您应该使用调度工具,如
at
cron
,如先前的答案所述,如;但是,如果您确实需要一个长时间运行的脚本,那么下面的脚本将一直运行到一天结束,轮询时间

因为它使用
printf%(…)T-1
来检查时间,而不是
date
命令,所以这种轮询的开销非常低(但需要bash 4.2或更高版本)。降低轮询率,如将
sleep 1
更改为
sleep 60
,将导致更高效但更慢的循环。请注意,
sleep
不能保证等待请求的确切时间(特别是在负载较重的系统上,
sleep 60
的睡眠时间可能比请求的60秒长),因此检查错过的轮询周期非常重要

#!/usr/bin/env bash

case $BASH_VERSION in ''|[123].*|4.[01].*) echo "ERROR: Bash 4.2 or newer required" >&2; exit 1;; esac

declare -A timestops=(
  [01:00]="abc.txt"
  [06:00]="def.txt"
  [13:00]="hij.txt"
  [23:00]="xyz.txt"
)

printf -v run_on_date '%(%Y-%m-%d)T' -1

printf -v last_time '%(%H:%M)T' -1
while sleep 1; do
  printf -v curr_time '%(%H:%M)T' -1
  printf -v curr_date '%(%Y-%m-%d)T' -1
  [[ "$curr_time" = "$last_time" ]] && continue
  [[ "$curr_date" = "$run_on_date" ]] || { echo "Day ${run_on_date} has ended; exiting" >&2; exit 0; }
  for evt_ts in "${!timestops[@]}"; do
    if [[ $curr_time = "$evt_ts" ]] || [[ $curr_time > $evt_ts && $last_time < $evt_ts ]]; then
      evt_file=${timestops[$evt_ts]}
      echo "THIS IS TEST FILE." >"/tmp/work/$evt_file"
    fi
  done
  last_time=$curr_time
done
#/usr/bin/env bash
“|[123].|4.[01].*)echo“ERROR:BASH 4.2或更新版本必需”>&2;出口1;;以撒
声明-A时间段=(
[01:00]=“abc.txt”
[06:00]=“def.txt”
[13:00]=“hij.txt”
[23:00]=“xyz.txt”
)
printf-v在日期“%”(%Y-%m-%d)T'-1运行
printf-v上一次“%”(%H:%M)T'-1
而睡眠1;做
printf-v当前时间“%”(%H:%M)T'-1
printf-v当前日期“%”(%Y-%m-%d)T'-1
[[“$curr\u time”=“$last\u time”]&&continue
[[“$curr_date”=“$run_on_date”]]|{echo”日${run_on_date}已结束;退出“>&2;退出0;}
对于“${!timestops[@]}”中的evt_ts;做
如果[[$curr_-time=“$evt_-ts”]||[$curr_-time>$evt_-ts&$last_-time<$evt_-ts]];然后
evt_文件=${timestops[$evt_ts]}
echo“这是测试文件。”>“/tmp/work/$evt_文件”
fi
完成
上次时间=$curr\u时间
完成

在大多数情况下,您应该使用调度工具,如
at
cron
,如先前存在的答案中所述;但是,如果您确实需要一个长时间运行的脚本,那么下面的脚本将一直运行到一天结束,轮询时间

因为它使用
printf%(…)T-1
来检查时间,而不是
date
命令,所以这种轮询的开销非常低(但需要bash 4.2或更高版本)。降低轮询率,如将
sleep 1
更改为
sleep 60
,将导致更高效但更慢的循环。请注意,
sleep
不能保证等待请求的确切时间(特别是在负载较重的系统上,
sleep 60
的睡眠时间可能比请求的60秒长),因此检查错过的轮询周期非常重要

#!/usr/bin/env bash

case $BASH_VERSION in ''|[123].*|4.[01].*) echo "ERROR: Bash 4.2 or newer required" >&2; exit 1;; esac

declare -A timestops=(
  [01:00]="abc.txt"
  [06:00]="def.txt"
  [13:00]="hij.txt"
  [23:00]="xyz.txt"
)

printf -v run_on_date '%(%Y-%m-%d)T' -1

printf -v last_time '%(%H:%M)T' -1
while sleep 1; do
  printf -v curr_time '%(%H:%M)T' -1
  printf -v curr_date '%(%Y-%m-%d)T' -1
  [[ "$curr_time" = "$last_time" ]] && continue
  [[ "$curr_date" = "$run_on_date" ]] || { echo "Day ${run_on_date} has ended; exiting" >&2; exit 0; }
  for evt_ts in "${!timestops[@]}"; do
    if [[ $curr_time = "$evt_ts" ]] || [[ $curr_time > $evt_ts && $last_time < $evt_ts ]]; then
      evt_file=${timestops[$evt_ts]}
      echo "THIS IS TEST FILE." >"/tmp/work/$evt_file"
    fi
  done
  last_time=$curr_time
done
#/usr/bin/env bash
“|[123].|4.[01].*)echo“ERROR:BASH 4.2或更新版本必需”>&2;出口1;;以撒
声明-A时间段=(
[01:00]=“abc.txt”
[06:00]=“def.txt”
[13:00]=“hij.txt”
[23:00]=“xyz.txt”
)
printf-v在日期“%”(%Y-%m-%d)T'-1运行
printf-v上一次“%”(%H:%M)T'-1
而睡眠1;做
printf-v当前时间“%”(%H:%M)T'-1
printf-v当前日期“%”(%Y-%m-%d)T'-1
[[“$curr\u time”=“$last\u time”]&&continue
[[“$curr_date”=“$run_on_date”]]|{echo”日${run_on_date}已结束;退出“>&2;退出0;}
对于“${!timestops[@]}”中的evt_ts;做
如果[[$curr_-time=“$evt_-ts”]||[$curr_-time>$evt_-ts&$last_-time<$evt_-ts]];然后
evt_文件=${timestops[$evt_ts]}
echo“这是测试文件。”>“/tmp/work/$evt_文件”
fi
完成
上次时间=$curr\u时间
完成

看看“cron”及其“crontab”这看起来像是一个严重混淆的“真正需要”(另请参见)问题在于,您会得到非常一般的答案,但很可能会遗漏您的实际问题。例如:是否需要每天在同一时间创建这些答案?文件名中的数字后缀如何,是每天从1开始还是继续增加?等等。更多详细信息==更好的答案。“只运行一次”(编辑后)?那么听起来您想要的是
at
作业,而不是
cron
作业。同样,我们已经有了适合任务的问答条目……如果您需要与我们已经讨论过的内容不同的内容,请务必清楚地解释为什么现有答案不适合任务(理想情况下,您是如何尝试应用它们的,以及这些尝试是如何/为什么失败的)。也许您应该添加autosys标记。看看“cron”及其“crontab”这看起来像是一个严重混淆的“真正需要”(另请参阅)问题在于,您会得到非常一般的答案,但很可能会遗漏您的实际问题。例如:是否需要每天在同一时间创建这些答案?文件名中的数字后缀如何,是每天从1开始还是继续增加?依此类推。更多详细信息==更好的答案。”只运行一次(编辑时)?听起来您想要的是
at
作业,而不是
cron
作业。同样,我们已经有了适合任务的Q&a条目……如果您需要与我们已经讨论过的内容不同的内容,请务必清楚地解释为什么现有答案不适合任务(理想情况下,你是如何尝试应用它们的,以及这些尝试是如何/为什么失败的)