这是一个shell脚本。请将受控环境随机数生成子shell推断为在异步日志记录情况下使用它(我打算将它用于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
显然,由于输入已完成,内循环已退出,变量的增量进入超级驱动。
如何退出循环?有没有类似else
的某种类型的break
子句,一旦输入完成后,我就可以破解内部for循环以便{{1}}退出外部循环?
当然,必须有一个更强大的方法,而不是在外循环中进行计时,看它是否过快。
答案 0 :(得分: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
答案 1 :(得分:1)
这是基于读取返回码的另一种解决方案。根据bash文档,当read -t
退出超时时,它的返回码大于128,因此您可以区分EOF和超时。
function random_timed_output
{
for val in {1..10}; do
sleep $(( $RANDOM/20000 ))
echo $val
done
}
group=0
random_timed_output | while true; do
read -t 1 line
rc=$?
if [ $rc -gt 128 ]; then
#read exit for timeout
((group++))
elif [ $rc -gt 0 ]; then
#read exit for error or EOF
break
else
#read exit OK
echo "read time=$group read=$line"
fi
done
答案 2 :(得分: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
无论如何都有帮助吗?