在 Bash 脚本中及时增加变量

在 Bash 脚本中及时增加变量

我想每 3 秒将变量增加 1。有没有办法使用 bash 来做到这一点?

我有一个程序在无限循环中运行,其中我正在使用变量做一些事情;我想增加该变量,例如每 3 秒增加一次,我不应该使用睡眠。

答案1

在 中bash$SECONDS特殊变量已经每秒递增一次,就像ksh特征的来源一样。

它在 shell 启动时初始化为 0(或者从$SECONDS环境变量的值(如果存在)初始化),但您也可以手动设置它的值。

但请注意bash的实现(与 ksh93、mksh 或 zsh 的实现相反,后两者曾经有相同的错误,但在我报告后已修复)是破碎的因为当系统时钟经过精确的秒标记时它就会递增。

因此,如果您将其设置0为 12:00:00.1 或 12:00:00.9,它将更改为112:00:01(因此在第一种情况下为 9/10 秒,在第二种情况下为 1/10 秒)

您可能想改用 zsh、mksh 或 ksh93。

然后你只需要使用$((SECONDS*3))每秒增加 3 的东西或$((SECONDS/3))每 3 秒增加 1 的东西。

在 中ksh93,您可以将get任意变量的规则定义为$((SECONDS*3))

#! /bin/ksh93 -
var.get() {
  .sh.value=$((int(SECONDS*3)))
}
SECONDS=0

# testing:
echo "$var"; sleep 1; echo "$var"

给出:

0
3

仍然在 ksh93 中,您可以定义一个typeof 变量,该变量每秒按任意数字递增,如下所示:

#! /bin/ksh93 -
SECONDS=0
typeset -T auto_incremented=(
  typeset -F start
  typeset -i initial=0
  typeset -i increment=1
  function get {
    .sh.value=$((_.initial + int((SECONDS - _.start) * _.increment)))
  }
  function create {
    ((_.start = SECONDS))
  }
  function set {
    _.initial=${.sh.value}
    ((_.start = SECONDS))
  }
)

# testing:
auto_incremented var
var.increment=2

echo "$var"; sleep 2; echo "$var"

var=10; echo "$var"; sleep 2; echo "$var"

这里给出:

0
4
10
14

虽然bash从 ksh 复制了很多功能,但它没有复制学科,类型或浮点数$SECONDS

在 中bash,您可以采取的一种方法是运行一些后台进程,该进程每秒发送一个信号bash并安装陷阱在更新变量的信号上,例如:

#! /bin/bash -
var=0 SECONDS=0; trap '((var = SECONDS * 3))' ALRM

ksh93 -c '
  t=0 SECONDS=0
  while
    sleep "$((++t - SECONDS))" && kill -s ALRM -- "$1" 2> /dev/null
  do
    : nothing
  done' ksh "$$" &

# testing:
echo "$var"; sleep 2; echo "$var"

请注意,我们不能只增加$var陷阱处理程序,因为陷阱仅在非内置命令之间进行处理,如果其中一个命令花费超过 1 秒,在此期间发送多个 SIGALRM 信号,则只会发送一个处理。

在这里,我们使用ksh93内联脚本每秒发送一次信号,但如果可用,您可以使用zsh, perl, ... 代替。python

答案2

一个可怕的解决方案:

#!/bin/bash
somevar=0
somefile=$(mktemp)
echo "$somevar" > "$somefile"
while true; do sleep 3; ((somevar++)); echo "$somevar" > "$somefile" ;done &

  while true; do

    sleep 1
    avar="$(cat "$somefile")"
    echo "my var has value $avar"

  done

当然与时俱进,而且远没有接近实时准备......

答案3

下面是代码

 i=10
    for ((j=1;j<=count_of_sequence;j++)); do echo $i; sleep 10;i=$(($i+1)); done

输出

10
11
12
13
14

相关内容