而[[condition]]在循环退出时暂停



我对ksh有一个问题,因为while循环无法遵守"while"条件。我现在应该补充一点,这是我的客户机Solaris机箱上的ksh88。(这是一个单独的问题,在这个论坛上无法解决。;)我看到了Lance的问题和一些类似的问题,但我发现没有一个能解决这个问题。(免责声明:不,我没有看过这个论坛上的每一个ksh问题)

下面是一段非常精简的代码,它复制了这个问题:

  1 #!/usr/bin/ksh
  2 #
  3 go=1
  4 set -x
  5 tail -0f loop-test.txt | while [[ $go -eq 1 ]]
  6 do
  7   read lbuff
  8   set $lbuff
  9   nwords=$#
 10   printf "Line has %d words <%s>n" $nwords "${lbuff}"
 11   if [[ "${lbuff}" = "0" ]]
 12   then
 13     printf "Line consists of %s; time to absquatulaten" $lbuff
 14     go=0        # Violate the WHILE condition to get out of loop
 15   fi
 16 done
 17 printf "nLooks like I've fallen out of the loopn"
 18 exit 0

我测试的方法是:

  • 在后台模式下运行loop-test.sh
  • 在另一个窗口中,我运行命令,如"echo some barries>>loop_test.txt"(当然没有引号)
  • 当我想退出时,我键入"echo 0>>loop test.txt"

会发生什么?它确实设置go=0并显示行:

行由0组成;吸收的时间

但是不退出循环。为了突破,我在txt文件中多加了一行。循环不处理该行,只是退出循环,在退出之前发出"退出"消息。

这是怎么回事?我不想使用"break",因为在实际的脚本中,循环监视数据库引擎的日志,当它看到引擎关闭的消息时,就会设置标志。实际的脚本在退出之前仍必须处理最后几行。

对想法持开放态度,有人吗?

非常感谢!

--J.

好吧,很快就失败了。在阅读了其他几篇帖子后,我发现了一个由dogbane给出的答案,它避开了我的整个计划。他的是(2013年)一个问题的第二个答案,我看到neeraj使用的是我正在使用的相同方案。

怎么了?到while的管道一直用于将要结束的输入,例如输出端不同的文件或命令。但是,从tail命令来看,没有明显的EOF。因此,while-in-a-subshell不知道何时终止。

多班恩的解决方案:不要使用管道。将他的逻辑应用于我的情况,基本循环是:

while read line do # put loop body here done < <(tail -0f ${logfile})

没有潜艇,没问题。

关于该语法的注意事项:两者之间必须有一个空格<运营商;否则,它看起来像一个语法不好的HEREIS文档。

呃,还有一个问题:语法在ksh中不起作用,甚至在模仿ksh93的mksh(在cygwin下)中也不起作用。但它在bash中确实起到了的作用。所以我的老板会嘲笑我的,因为他知道我不喜欢bash。

所以非常感谢,dogbane。

--J

在阐明问题并解决问题后,我想到了所描述行为的原因:在设置go=0后,循环的控制流仍然依赖于通过该管道从STDIN传入的另一行数据。

现在我已经意识到了奇怪的原因,我可以从流中推测另一种阅读方式。目前,我正在考虑以下解决方案:

  • 以STDIN打开输入文件(需要研究exec语法)
  • 当条件发生时,关闭STDIN(同样,需要研究语法)

然后,在循环的顶部使用更直观的while read lbuff应该是安全的。

我今天会测试一下并公布结果。我希望其他人能从这种方法中受益(如果有效的话)。

最新更新