在bash脚本仍在运行时强制将输出刷新到文件

ola*_*ndo 72 bash file flush

我有一个小脚本,crontab每天使用以下命令调用它:

/homedir/MyScript &> some_log.log
Run Code Online (Sandbox Code Playgroud)

此方法的问题是some_log.log仅在MyScript完成后创建.我希望在程序运行时将程序的输出刷新到文件中,这样我就能做到这样的事情

tail -f some_log.log
Run Code Online (Sandbox Code Playgroud)

并跟踪进度等

Mar*_*sch 69

我在这里找到了解决方案.使用OP的例子,你基本上运行

nohup

然后在每行输出后刷新缓冲区.我经常把它与nohup远程机器上的长作业结合起来.

nohup

这样,当您注销时,您的进程不会被取消.

  • 该链接不再可用. (5认同)
  • @NicHartley:`stdbuf` 是 GNU coreutils 的一部分,[文档可以在 gnu.org 上找到](https://www.gnu.org/software/coreutils/manual/html_node/stdbuf-invocation.html#stdbuf-invocation ) (3认同)
  • 你能添加一个指向`stdbuf`的一些文档的链接吗?基于 [此评论](http://stackoverflow.com/questions/1429951/bash-how-to-flush-output-to-a-file-while-running?answertab=votes#comment4951700_4520994) 似乎不是在某些发行版上可用。你能澄清一下吗? (2认同)

Chr*_*odd 27

bash本身永远不会将任何输出写入您的日志文件.相反,它作为脚本的一部分调用的命令将分别编写输出并在它们感觉到时刷新.所以你的问题实际上是如何强制bash脚本中的命令刷新,这取决于它们是什么.

  • 我真的不明白这个答案. (7认同)
  • 十年后,这是显而易见的,但这是一条评论,而不是一个答案,也不应该是公认的答案。 (7认同)
  • 为了更好地了解标准输出的行为,请查看http://stackoverflow.com/a/13933741/282728.短版本 - 默认情况下,如果重定向到文件,则stdout完全缓冲; 它只在刷新后写入文件.Stderr不是 - 每次'\n'后写的.一种解决方案是使用下面的user3258569推荐的'script'命令,在每行结束后刷新stdout. (2认同)

小智 23

__CODE__

关键是-f.从man脚本引用:

script -c <PROGRAM> -f OUTPUT.txt
Run Code Online (Sandbox Code Playgroud)

在后台运行:

-f, --flush
     Flush output after each write.  This is nice for telecooperation: one person
     does 'mkfifo foo; script -f foo', and another can supervise real-time what is
     being done using 'cat foo'.
Run Code Online (Sandbox Code Playgroud)


cre*_*ate 9

您可以使用tee写入文件而无需刷新.

/homedir/MyScript 2>&1 | tee some_log.log > /dev/null
Run Code Online (Sandbox Code Playgroud)

  • 至少在我的Ubuntu 18.04环境中,这仍然会缓冲输出。内容最终会以任何一种方式写入文件,但是我认为OP要求一种方法,它们可以在文件完成写入之前更准确地监视进度,并且该方法除了输出重定向之外,还不能做任何其他事情。做。 (2认同)

Gre*_*ill 6

这不是 的函数bash,因为 shell 所做的只是打开相关文件,然后将文件描述符作为脚本的标准输出传递。您需要做的是确保比当前更频繁地从脚本中刷新输出。

例如,在 Perl 中,这可以通过设置来完成:

$| = 1;
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅perlvar 。


Ond*_*žka 6

这有帮助吗?

tail -f access.log | stdbuf -oL cut -d ' ' -f1 | uniq 
Run Code Online (Sandbox Code Playgroud)

这将立即使用stdbuf 实用程序显示 access.log 中的唯一条目。