跟踪最近的文件

5

我有一个程序在运行时会将输出记录到*.out文件中。我设置了一个bash脚本多次运行,这样每次运行都会写入一个不同的*.out文件。我发现可以像这样使用tail命令来查看最近的*.out文件:

watch tail $(ls -tr *.out | tail -n1)

问题似乎在于引用$()只执行一次。因此,当第一次运行完成时,watch继续监视相同的*.out文件,即使现在有一个更新的*.out文件也是如此。
我该如何修改它以在一次运行完成后转到下一个*.out文件?
我尝试过嵌套引号和括号,但我不太了解引用的详细信息。事情变得复杂起来的原因是watch将其命令传递给sh,而我正在使用bash。
加分项:如果可以将其修改为tail -f而不仅仅是每n秒重复watch,那就太好了。

2
嗯...我真的不理解使用情况。你想实时读取几个文件吗?如果是的话,使用 tail -f *.out 更容易。 - pivanchy
我基本上同意 @pivanchy 的观点,尽管值得一提的是 POSIX 的 tail 并不能保证同时处理多个文件。 - kojiro
@pivanchy 那就是解决方案。我没有意识到它是那么简单的。 - Jeff Irwin
1
@JeffIrwin 这并不是因为 bash 只会匹配当前所有文件。 - steffen
@JeffIrwin,您的意思是需要运行一次命令,但在此期间(命令仍在进行时)需要删除并创建新文件吗? - pivanchy
显示剩余3条评论
3个回答

3
我也遇到了这个问题,最终找到了以下解决方案:
 watch "ls -t1 | sed q | xargs tail"

需要在奖励方面有些“hacky”。tail命令还支持一个参数--pid,它使得tail随着引用的PID死亡而立即死亡。听起来不错?这里是一些模式可以使用:

while true; do ls -t1 | sed q | xargs lsof -F np | sed 's/.\(.*\)/\1/g' | xargs tail -f --pid 2>/dev/null ; done

这基本上是跟踪最新的文件并在文件写入过程结束时重新启动tail


谢谢!我只需要添加一个简单的文件过滤器,就像这样:watch ls -t1 *.out | sed q | xargs tail" - Jeff Irwin
1
@JeffIrwin 也试试编辑功能。它不再观察文件,而是直接跟随输出(使用tail)。 - steffen
1
编辑功能很棒!我甚至不想尝试理解所有的管道。 - Jeff Irwin

1
如果所有文件一开始就存在,并且您有一个可以处理多个文件的现代实现的tail
tail -f *.out

看起来是最好的解决方案。但如果你一开始没有所有的文件,那么最简单的方法还是创建它们。 *.out 只会扩展到你已经拥有的文件。

但如果在开始之前你无法知道 tail -f 的文件名,则需要在 tailing 时重新启动 tail,如果有任何新的 outfiles 被创建。在这种情况下,考虑到你每次只写一个 outfile,你可以这样做:

inotifywait -m -e create -q . | while read dir event file; do
    kill %tail
    tail -f "$file" &
done
kill %tail

(以上需要使用inotifywait,它包含在Debian系系统如Ubuntu中的inotify-tools中。)它监视当前目录中新创建的文件,后台跟踪所创建的任何文件,并在创建新文件时终止先前的跟踪命令。

0

所以,我会稍微复制一下我的当前答案:

跟踪最近的文件

你可以使用非常简单的命令来解决你的问题:

tail -f *.out

tail也可以处理多个文件,使用方法如下:

tail -f file1 file2 file3

所以,正如您所看到的,它是非常强大且易于使用的工具,您不需要玩弄Linux命令


这并没有解决问题,即 * 由 shell 评估,因此在 tail 初始运行后创建的任何文件都将永远不会被跟踪。 - dpwr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接