shell中的时间条件循环

Mih*_*hir 35 shell

我刚刚开始学习shell脚本,所以我对它不太了解.

我试图找到基于时间循环的例子,但没有任何运气.

我想在特定的时间内运行循环,比方说1小时.所以循环运行一个小时然后自动结束.

编辑:此循环将连续运行而没有任何睡眠,因此循环条件应基于循环的开始时间和当前时间,而不是基于睡眠.

bsr*_*nin 67

执行此操作的最佳方法是使用$ SECONDS变量,该变量具有脚本(或shell)运行时间的计数.下面的示例显示了如何运行while循环3秒.

#! /bin/bash
end=$((SECONDS+3))

while [ $SECONDS -lt $end ]; do
    # Do what you want.
    :
done
Run Code Online (Sandbox Code Playgroud)

  • 这是由 bash 和可能的其他 bourne shell 变体支持的,但我不确定它是否在 POSIX 规范中,因此您应该清楚地指定一个比 `#!/bin/sh`(这是答案是肯定的,但我只是指出了这一点)。 (2认同)
  • +1 使用`$SECONDS`;@RobStarling:它确实不是 POSIX 的一部分(请参阅我对仅 POSIX 解决方案的回答);非详尽调查:`$SECONDS` 适用于`bash`、`zsh`、`ksh​​`。在 `ksh` 中,它甚至报告小数秒。 (2认同)

mkl*_*nt0 19

警告:这个答案中的所有解决方案 - 除了ksh一个 - 都可以提前返回(但不包括)1秒,因为它们基于一个基于实时(系统)时钟而不是基于实时(系统)时钟前进的积分秒计数器.基于代码执行何时开始.


bash,ksh,zsh溶液,使用特殊的外壳变量$SECONDS:

@ bsravanin答案的略微简化版本.

松散地说,$SECONDS包含脚本中到目前为止经过的秒数.

bashzsh你通过系统(实时)时钟的脉冲推进积分秒- 即,在幕后计数并不真正从(!)开始,但是在上一个完整时间秒之后的任何分数脚本碰巧开始或变量被重置.0SECONDS

相比之下,ksh按照人们的预期运作:计数真正从0重置时开始$SECONDS; 此外,$SECONDS报告数秒ksh.

因此,该解决方案唯一合理可预测和精确工作的外壳是ksh.也就是说,对于粗略的测量和超时,它仍然可用于bashzsh.

注意:以下使用bashshebang线; 简单地替代ksh或者zsh用于bash将与这些炮弹运行该脚本了.

#!/usr/bin/env bash

secs=3600   # Set interval (duration) in seconds.

SECONDS=0   # Reset $SECONDS; counting of seconds will (re)start from 0(-ish).
while (( SECONDS < secs )); do    # Loop until interval has elapsed.
  # ...
done
Run Code Online (Sandbox Code Playgroud)

POSIX-features-only shell的解决方案,例如Ubuntu上的sh(dash)($SECONDS不符合POSIX)

清理版@ dcpomero的答案.

使用由date +%s(1970年1月1日以来经过的秒数)返回的纪元时间和条件的POSIX语法.

警告:date +%s本身(具体来说,%s格式)符合POSIX标准,但它(至少)可以在Linux,FreeBSD和OSX上运行.

#!/bin/sh

secs=3600                         # Set interval (duration) in seconds.
endTime=$(( $(date +%s) + secs )) # Calculate end time.

while [ $(date +%s) -lt $endTime ]; do  # Loop until interval has elapsed.
    # ...
done
Run Code Online (Sandbox Code Playgroud)