我想每 3 秒将变量增加 1。有没有办法使用 bash 来做到这一点?
我有一个程序在无限循环中运行,其中我正在使用变量做一些事情;我想增加该变量,例如每 3 秒增加一次,我不应该使用睡眠。
答案1
在 中bash
,$SECONDS
特殊变量已经每秒递增一次,就像ksh
特征的来源一样。
它在 shell 启动时初始化为 0(或者从$SECONDS
环境变量的值(如果存在)初始化),但您也可以手动设置它的值。
但请注意bash
的实现(与 ksh93、mksh 或 zsh 的实现相反,后两者曾经有相同的错误,但在我报告后已修复)是破碎的因为当系统时钟经过精确的秒标记时它就会递增。
因此,如果您将其设置0
为 12:00:00.1 或 12:00:00.9,它将更改为1
12: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 中,您可以定义一个type
of 变量,该变量每秒按任意数字递增,如下所示:
#! /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