Bash 如果输入由一个内部的";当读到“时?”;?
这是一个shell脚本。请推断受控环境随机数生成子shell在异步日志记录情况下的使用(我打算将其用于inotifywait输出) 这将产生如下输出:Bash 如果输入由一个内部的";当读到“时?”;?,bash,shell,unix,Bash,Shell,Unix,这是一个shell脚本。请推断受控环境随机数生成子shell在异步日志记录情况下的使用(我打算将其用于inotifywait输出) 这将产生如下输出: 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 rea
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
但它会挂起,不会退出。它卡在外部循环中,不断增加组:
$ echo $group
1336794
显然,由于输入已完成,内部循环已退出,变量的增量进入hyperdrive
如何退出循环?是否有一个类似于else
的子句,我可以在输入完成后,通过它进入内部for循环,从而中断外部循环
当然,一定有一种比在外循环中计时更可靠的方法来检查它是否通过得太快 #/bin/bash
#!/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
mkfifo输出
对于{1..10}中的val;做
echo“$RANDOM/20000”| bc | xargs睡眠
echo$val
完成>输出&
组=0
时间=$(日期+%s%N)
读行时;做
ctime=$(日期+%s%N)
[$($ctime-$time))-gt 100000000]&租赁集团++
echo“读取时间=$组读取=$行”
时间=$ctime
完成<输出
输出不令人满意,但我稍后会查看:
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
这有帮助吗?这是另一个基于读取返回代码的解决方案。根据bash文档,当read-t
exit for timeout时,它的返回码大于128,因此可以区分EOF和timeout
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
您是否尝试过中断n
。。。。n您可以指定要退出的嵌套/循环数。。。。(如果检查break 2 stmt。)注意我怎么从来没有写过break
。它会去哪里?内部循环每秒都会超时。这是一个有趣的问题,+1。一个有争议的问题,它看起来应该放在哪里?我能想到的唯一一件事是使内部循环也成为无限循环,然后当我从阅读中注意到正确的条件时,手动断开两个循环。好吧,解决这个毫无意义的示例问题是合理的,但在现实生活中,我不知道我的日志会就此结束,是吗?根据manpage,read-t
超时时返回false。当输入结束时,它不也返回false吗?因此,我无法判断输入何时结束。至于第二点,我承认,edit输入来自哪里?inotifywait-m
。尝试“收集”输出,以便在我更改50个文件时不会运行脚本50次simultaneously@Steven鲁,好的。。。。。Sry我没有看这一点,只是想弄清楚为什么读取失败??也许你的$($RANDOM/10000))
不如我原来的好,有时写零字节,或者做了一些奇怪的事情?现在我更困惑了….@史蒂夫,你能提供更多关于你想做什么的信息吗。。。如果你同意的话,用实际场景编辑问题本身?是的,就是这样。。。。。我分别测试了它,有时它确实给出0。。。但是对于睡眠,var是由for计数器设置的,该计数器在通过管道时回显到读入。。。。。未分配的原因:(我不知道。阅读这里的其他内容来了解我回答这个问题的动机。我相信@perreal很好地解决了这个问题,如果我能找到一个解决方案,我以后可能会用非fifo管道解决方案发回。不在CentOS上。两种情况都返回1。你在哪里测试过这个问题?@StevenLu:Ubuntu13.04,bash 4.2,另请参阅此处内置的“阅读”文档:嗯然后。%bash——GNUBash版本,3.2.25(1)版本——发行版(x86_64-redhat-linux-GNU)
我认为使用手动定时器可以提高移植性。但肯定是+1。
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
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