Bashスクリプトでタイムリーに変数を追加する

Bashスクリプトでタイムリーに変数を追加する

3秒ごとに変数を1ずつ増やしたいです。 bashを使ってこれを行う方法はありますか?

変数を使用してタスクを実行する無限ループで実行されるプログラムがあります。たとえば、3秒ごとに変数を増やしたいとします。睡眠を使用しないでください。

答え1

では、機能のソースと同様に、特殊変数はすでに毎秒増加しますbash$SECONDSksh

$SECONDSシェルの起動時に(または環境変数がある場合は環境変数の値から)0に初期化されますが、その値を手動で設定することもできます。

ただし、bash実装は(同じバグがあったが報告した後に修正されたksh93、mksh、またはzshの実装とは反対)、次のようになります。壊れたシステムクロックは、正確な2番目のマーキングを通過すると増加するためです。

したがって、12:00:00.1または12:00:00.9に設定すると、12:00:010に変更されます1(つまり、最初の場合は9/10秒、2番目の場合は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

typeksh93では、次のように、毎秒数が増加する 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

kshから多くの機能がコピーされますが、bashコピーされません。トピックタイプまたは浮動小数点数$SECONDS

取ることができる1つのアプローチ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つが1秒以上かかり、その間に複数のSIGALRM信号を送信した場合は、1つのハンドラのみが追加されます。送信された。

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

関連情報