Unix 突破;尾部-f“;那';正在读的是一个;当读到;HP-UX中的循环

Unix 突破;尾部-f“;那';正在读的是一个;当读到;HP-UX中的循环,unix,shell,tail,hp-ux,Unix,Shell,Tail,Hp Ux,我正在尝试编写一个(sh-bourneshell)脚本,在将行写入文件时对其进行处理。我试图通过将tail-f的输出输入到while read循环中来实现这一点。基于我在谷歌的研究以及处理类似问题的经验,这种策略似乎是合适的,但使用的是bash 从我所读到的,似乎我应该能够打破循环时,所遵循的文件不再存在。没有。事实上,似乎我能摆脱这种局面的唯一方法是在另一个会话中终止进程尾部似乎工作正常,否则使用以下方法进行测试: touch file tail -f file | while read li

我正在尝试编写一个(sh-bourneshell)脚本,在将行写入文件时对其进行处理。我试图通过将
tail-f
的输出输入到
while read
循环中来实现这一点。基于我在谷歌的研究以及处理类似问题的经验,这种策略似乎是合适的,但使用的是bash

从我所读到的,似乎我应该能够打破循环时,所遵循的文件不再存在。没有。事实上,似乎我能摆脱这种局面的唯一方法是在另一个会话中终止进程<代码>尾部似乎工作正常,否则使用以下方法进行测试:

touch file tail -f file | while read line do echo $line done 触摸文件 tail-f文件|在读取行时 做 回音$线 完成 在另一个会话中,我附加到
文件中的数据显示为上面所述循环处理中的文件

这在HP-UX版本B.11.23上


感谢您提供的任何帮助/见解

我不知道HP-UX
tail
,但GNU
tail
--follow=name
选项,该选项将按名称跟随文件(每隔几秒钟重新打开一次文件,而不是从相同的文件描述符读取,该描述符不会检测文件是否已解除链接)并将在用于打开文件的文件名取消链接时退出:

tail --follow=name test.txt

如果您想在文件不再存在时中断,只需执行以下操作:

 test -f file || break
把这个放在你的循环中,应该会爆发

剩下的问题是,如何中断读取行,因为这是阻塞

这可以通过应用超时来实现,比如read-t5行。然后每隔5秒读取返回一次,如果文件不再存在,循环将中断。注意:创建循环,使其能够处理该情况,读取超时,但文件仍然存在

编辑:似乎with timeout read返回false,因此您可以将测试与超时结合起来,结果将是:

  tail -f test.file | while read -t 3 line || test -f test.file; do 
          some stuff with $line
  done
除非您使用的是GNUtail,否则在跟踪文件时它不可能自动终止。-f选项实际上只用于交互式监视——事实上,我有一本书说-f“不太可能在shell脚本中使用”

但对于问题的解决方案,我不完全确定这是否是一种过度设计的方法,但我认为您可以将尾部发送到FIFO,然后使用函数或脚本检查文件是否存在,如果未链接,则删除尾部

#!/bin/sh sentinel () { while true do if [ ! -e $1 ] then kill $2 rm /tmp/$1 break fi done } touch $1 mkfifo /tmp/$1 tail -f $1 >/tmp/$1 & sentinel $1 $! & cat /tmp/$1 | while read line do echo $line done #!/垃圾箱/垃圾箱 哨兵() { 虽然是真的 做 如果[!-e$1] 然后 杀死2美元 rm/tmp/$1 打破 fi 完成 } 触摸1美元 mkfifo/tmp/$1 尾部-f$1>/tmp/$1& 哨兵1美元& cat/tmp/$1 |读线时 做 回音$线 完成
做了一些天真的测试,它似乎工作正常,没有留下任何垃圾。

我从来没有对这个答案感到满意,但我也没有找到替代方案:

kill $(ps -o pid,cmd --no-headers --ppid $$ | grep tail | awk '{print $1}')

获取当前进程的所有子进程,查找尾部,打印出第一列(尾部的pid),并终止它。Sin-freaked丑陋,生活就是如此。

以下方法将
tail-f file
命令作为背景,将其进程id加上一个自定义字符串前缀(此处
tailpid:
)回送到
,而
循环中带有自定义字符串前缀的行触发另一个(后台)
while
循环,每5秒检查
文件是否仍然存在。否则,
tail-f文件
将被终止,并且包含后台
的子shell将退出
循环

# cf. "The Heirloom Bourne Shell",
# http://heirloom.sourceforge.net/sh.html,
# http://sourceforge.net/projects/heirloom/files/heirloom-sh/ and
# http://freecode.com/projects/bournesh

/usr/local/bin/bournesh -c '
touch file
(tail -f file & echo "tailpid: ${!}" ) | while IFS="" read -r line
do
   case "$line" in
      tailpid:*) while sleep 5; do 
                       #echo hello; 
                       if [ ! -f file ]; then
                          IFS=" "; set -- ${line}
                          kill -HUP "$2"
                          exit
                       fi
                 done & 
                 continue ;;
   esac
   echo "$line"
done
echo exiting ...
'

你好,罗伯特。我确实在谷歌搜索中看到了这个选项,听起来是最好的选择。很遗憾,HP-UX不支持此选项。@代理-您可以下载并编译(端口)GNU tail吗?这看起来确实是你想要的。@tvanfosson-这是一个有趣的项目,可以模拟我们刚刚移植的系统(MPE)的一些功能。这只是为了让开发者的生活更轻松一点。我怀疑我能否获得批准在dev中编译GNU tail,更不用说生产(对于oncall工作来说是一个有用的工具)如果没有新数据添加到文件中,这将保持每3秒处理一次最新的行。这就是为什么我写:“注意:创建您的循环,它可以处理案例,读取超时,但文件仍然存在。”这句话非常含糊,没有说明此解决方案的问题。