如何使bash命令定期运行?

如何使bash命令定期运行?,bash,Bash,我想执行一个脚本,让它每x分钟运行一个命令 另外,关于学习bash脚本的任何资源的任何一般性建议都可能非常酷。我使用Linux进行个人开发工作,因此bash脚本对我来说并不完全陌生,我只是没有从头开始编写自己的脚本。如果您想定期运行命令,有3种方法: 使用crontab命令,例如***命令(每分钟运行一次) 使用如下循环:while true;do./my_script.sh;睡眠60;完成(不精确) 使用 看 关于最佳bash脚本实践的一些建议: 指南: 参考: 使用更多引号!: 脚本

我想执行一个脚本,让它每x分钟运行一个命令


另外,关于学习bash脚本的任何资源的任何一般性建议都可能非常酷。我使用Linux进行个人开发工作,因此bash脚本对我来说并不完全陌生,我只是没有从头开始编写自己的脚本。

如果您想定期运行命令,有3种方法:

  • 使用
    crontab
    命令,例如
    ***命令(每分钟运行一次)
  • 使用如下循环:
    while true;do./my_script.sh;睡眠60;完成
    (不精确)
  • 使用

关于最佳bash脚本实践的一些建议:


指南:
参考:

使用更多引号!:
脚本及更多:

我想执行脚本并让它每隔{time interval}运行一个命令

cron
()就是为此而设计的。如果运行
mancron
mancrontab
,您将找到如何使用它的说明

关于学习bash脚本的任何资源的任何一般性建议都可能非常酷。我在个人开发工作中使用Linux,所以bash脚本对我来说并不完全陌生,我只是没有从头开始编写自己的脚本


如果您对使用bash感到满意,我建议您首先阅读bash手册页(
manbash
)——这里有很多很酷的花絮。

除了@sputnick的答案之外,还有
watch
。从手册页:

Execute a program periodically, showing output full screen

默认情况下,这是每2秒一次<例如,code>watch
对于
tail
ing日志非常有用。

macOS用户:下面是GNU
watch
命令的部分实现(从版本
0.3.0
开始),用于主要用于目视检查的交互式定期调用:

它的语法与GNU版本兼容,如果使用了未实现的特性,则会出现特定的错误消息

值得注意的局限性:

  • 输出不限于一屏
  • 不支持显示输出差异
  • 不支持使用精确计时
  • 彩色输出总是通过(
    --暗示颜色)
还实现了一些非标准功能,例如等待成功(
-E
)以补充等待错误(
-E
),并显示最近一次调用的时间以及到目前为止经过的总时间

有关详细信息,请运行
watch-h

示例:

watch -n 1 ls # list current dir every second
watch -e 'ls *.lockfile' # list lock files and exit once none exist anymore.
源代码(粘贴到名为
watch
的脚本文件中,使其可执行,并放置在
$PATH
的目录中;请注意,此处的语法高亮显示已中断,但代码仍然有效):

#/usr/bin/env bash
此\u名称=$(basename“$BASH\u SOURCE”)
版本='0.1'
#用于因运行时错误而退出并显示错误消息的帮助器函数。
#死亡[errMsg[exitCode]]
#默认错误消息表示上下文并指示中止执行。默认退出代码为1。
#上下文的前缀始终在前面。
#注意:错误消息*始终*打印;如果您只想以静默方式退出特定代码,请直接使用'exit n'。
死(){
echo“$THIS_NAME:ERROR:${1:-”由于意外错误而中止。“}”1>&2
退出${2:-1}#注意:如果参数是非数字的,shell将打印一条警告并使用退出代码255。
}
#用于退出的帮助函数,由于参数无效而显示错误消息。
#语法错误[errMsg]
#提供默认错误消息,以及前缀和后缀;退出代码始终为2。
语法(){
echo“$THIS_NAME:PARAMETER ERROR:${1:-”指定的参数无效。}请使用-h获取帮助。1>&2
出口2
}
#以HH:MM:SS格式获取自指定历元时间以来经过的时间。
#粒度:整秒。
#例如:
#tsStart=$(日期+“%s”)
#   ...
#getElapsedTime$tsStart
getElapsedTime(){
日期-j-u-f'%s'$($(日期+'%s')-$1))++'%H:%M:%s'
}
#命令行帮助。
如果[[“$1”='--help'| |“$1”='-h'];然后
cat让bash直接运行它。
"$@"
fi
fi
ec=$?
((ec!=0&&beeponer))&&printf'\a'
((ec==0&&rununtlsuccess))&&{echo$'\n'[$(日期+'%H:%M:%S')-经过:$(getElapsedTime$tsStart)]按请求退出:报告退出代码0。“>&3;退出0;}
((ec!=0&&runUntilFailure))&&{echo$'\n'[$(日期+'%H:%M:%S')-经过:$(getElapsedTime$tsStart)]按请求退出:报告非零退出代码($ec)。>&3;退出0;}
睡眠时间间隔
完成
  • 如果需要直观地监视给出静态输出的命令,请使用
    watch[options]command
    。例如,要监视可用内存,请运行:

    watch -n 1 free -m
    
    其中
    -n1
    选项将更新间隔设置为1秒(默认值为2秒)
    查看
    man watch
    或以了解详细信息


  • 如果您需要直观地监视日志文件中的更改,
    tail
    是您选择的命令,例如:

    tail -f /path/to/logs/file.log
    
    其中
    -f
    (表示“follow”)选项告诉程序在文件增长时输出附加数据
    有关详细信息,请查看
    人尾


  • 避免时间漂移

    以下是我如何消除命令运行所需的时间,并仍然按计划执行:

    #每600秒执行一次命令,避免时间漂移
    #以10分钟的倍数运行命令
    而sleep$(echo 600-`date'+%s'`%600|bc);不做ls;完成
    
    这将漂移不超过1秒。然后它会与时钟同步。如果您需要小于1秒的漂移,并且您的sleep命令支持浮点数,请尝试在计算中添加纳秒,如下所示

    whilesleep$(echo 6-`date'+%s.%N'`6|bc);执行日期'+%FT%T.%N';完成
    
    我面临着危险
    tail -f /path/to/logs/file.log
    
    CURRENT_TIME=$(date "+%s")
    LAST_SCRIPT_RUN_TIME=$(date -r "$0" "+%s")
    TIME_INTERVAL='3600'
    START_TIME=$(date -d '07:00:00' "+%s")
    END_TIME=$(date -d '16:59:59' "+%s")
    TIME_DIFFERENCE=$((${CURRENT_TIME} - ${LAST_SCRIPT_RUN_TIME}))
    TIME_CONDITION=$((${START_TIME} <= ${CURRENT_TIME} && ${CURRENT_TIME} <= $END_TIME}))
    
    
    if [[ "$TIME_DIFFERENCE" -le "$TIME_INTERVAL" ]];
        then
            >&2 echo "[ERROR] FAILED - script failed to run because of time conditions"
    elif [[ "$TIME_CONDITION" = '0' ]];
        then
            >&2 echo "[ERROR] FAILED - script failed to run because of time conditions"
    elif [[ "$TIME_CONDITION" = '1' ]];
        then
            >&2 touch -m "$0"
            >&2 echo "[INFO] RESULT - script ran successfully"
    fi
    
    tpid=0
    while true; do
      wait ${tpid}
      sleep 3 & tpid=$!
      { body...; }
    done
    
    timer | { while read ev; do...; done; }