3

ここにシェルスクリプトがあります。制御環境の乱数生成サブシェルを、非同期ログの状況でこれを使用するように推定してください (私は inotifywait 出力に使用する予定です)。

group=0
(
  for val in {1..10}; do 
    echo "$RANDOM/20000" | bc | xargs sleep # this waits 0, 1, or 2 seconds before each number is printed
    echo $val 
  done 
) | while true; do 
      while read -t 1 line; do 
        echo "read time=$group read=$line" 
      done
      ((group++))
    done

これにより、次のような出力が生成されます。

read time=1 read=1
read time=2 read=2
read time=2 read=3
read time=3 read=4
read time=3 read=5
read time=3 read=6
read time=4 read=7
read time=5 read=8
read time=5 read=9
read time=5 read=10

しかし、その後ハングして終了しません。外側のループでスタックし、継続的にインクリメントしますgroup:

$ echo $group 
1336794

明らかに、入力が終了したために内側のループが終了し、変数のインクリメントがハイパードライブに入りました。

ループから抜け出すには?入力の受信が完了したら、外側のループから抜け出すために内側の for ループにハックできるようなelse節のようなものはありますか?break

確かに、外側のループでタイミングを実行して速度が速すぎるかどうかを確認するよりも堅牢な方法が必要です。

4

3 に答える 3

3
#!/bin/bash
mkfifo outputs
for val in {1..10}; do
    echo "$RANDOM/20000" | bc | xargs sleep
    echo $val 
done > outputs &
group=0
time=$(date +%s%N)
while read line; do
    ctime=$(date +%s%N)
    [ $(( $ctime - $time )) -gt 1000000000 ] && let group++
    echo "read time=$group read=$line"
    time=$ctime
done < outputs
于 2013-06-06T04:18:29.557 に答える
0
 Kaizen ~/so_test $ cat zcntr.sh
 ilimit=10; ## the length of list in for loop ... 

grp=0
(   for val in {1..10}; do
     #echo "$RANDOM/10000" | bc | xargs sleep
     sleep $(($RANDOM/10000));
     echo $val
     done
 ) | while true; do

  while read -t 1 line; do
    echo "read time=$grp read=$line"
  done

  ((grp++));

  if [ $grp -eq $ilimit ]
     then
       break ;
  fi

done

出力は満足のいくものではありませんが、後で見てみましょう:

Kaizen ~/so_test $ ./zcntr.sh
  read time=0 read=1
  read time=0 read=2
  read time=1 read=
  read time=1 read=4
  read time=1 read=5
  ./zcntr.sh: line 13: read: read error: 0: Permission denied
  read time=4 read=7
  read time=6 read=
  read time=7 read=
  read time=7 read=10

これはとにかく役立ちますか?

于 2013-06-06T04:40:28.677 に答える