每 X 秒执行一次命令

use*_*531 11 shell bash sleep shell-script watch

我希望每 10 秒执行一次命令,并在后台执行它(从而消除watch?)。所有答案都显示如下内容,但这将执行 11 到 14 秒。如何做到这一点?

while true; do
    # perform command that takes between 1 and 4 seconds
    sleep 10
done
Run Code Online (Sandbox Code Playgroud)

The*_*kin 17

怎么样:

( # In a subshell, for isolation, protecting $!
  while true; do
    perform-command & # in the background
    sleep 10 ;
    ### If you want to wait for a perform-command
    ### that happens to run for more than ten seconds,
    ### uncomment the following line:
    # wait $! ;
    ### If you prefer to kill a perform-command
    ### that happens to run for more than ten seconds,
    ### uncomment the following line instead:
    # kill $! ;
    ### (If you prefer to ignore it, uncomment neither.)
  done
)
Run Code Online (Sandbox Code Playgroud)

ETA:有了所有这些评论、替代方案和额外保护的子外壳,这看起来比开始时复杂得多。因此,为了进行比较,以下是我开始担心waitor 之前的情况kill,以及它们$!和需要隔离的情况:

while true; do perform-command & sleep 10 ; done
Run Code Online (Sandbox Code Playgroud)

剩下的真的只是在你需要的时候使用。

  • 此外,引用您的代码适用于哪个 shell(如 mikeserv 的回答),这样当不同的 shell 表现不同时人们就不会感到困惑:) (2认同)

mik*_*erv 10

你可以这样做以下的bash,zsh或ksh:

SECONDS=0
while   command
do      sleep "$((10-(SECONDS%10)))"
done
Run Code Online (Sandbox Code Playgroud)

以下是bash手册所说的内容$SECONDS:

$SECONDS

  • 每次引用此参数时,都会返回自调用 shell 以来的秒数。如果将值分配给$SECONDS,则后续引用返回的值是自分配以来的秒数加上分配的值。如果$SECONDS是unset,它会失去它的特殊属性,即使它随后被重置。

这是一个工作示例:

SECONDS=0
while   command
do      sleep "$((10-(SECONDS%10)))"
done
Run Code Online (Sandbox Code Playgroud)
(   SECONDS=0
    while   sleep   "$((RANDOM%10))"
    do      sleep   "$((10-(SECONDS%10)))"
            echo    "$SECONDS"
    done
)
Run Code Online (Sandbox Code Playgroud)

  • 为了避免重置`SECONDS`,请执行`sleep "$((10-(($SECONDS-$start_time)%10)))"`。您必须在循环之前执行 `start_time=$SECONDS`。 (2认同)