有没有一种方法可以将输出重定向到文件而无需在unix / linux上进行缓冲?


49

我有一个运行很长时间的批处理过程,该过程将一些调试和过程信息输出到stdout。如果我只是从终端运行,则可以跟踪“它在哪里”,但是数据变得太多,并滚动到屏幕之外。

如果我将输出重定向到文件“> out.txt”,则最终会得到整个输出,但会对其进行缓冲,因此我不再能看到它现在正在做什么。

有没有一种方法可以重定向输出但不缓冲其写入?


1
您能否看一下下面的我的(和@cnst的)“辩论”,我想您唯一想做的就是在将输出记录到文件的同时查看输出。如果您找到了解决方案,请告诉我们;)!

Answers:


52

您可以使用setvbufC中的调用来显式设置标准流的缓冲选项(请参阅此链接),但是如果您要修改现有程序的行为,请尝试stdbufcoreutils显然是从7.5版开始的一部分)。

stdout最多缓冲一行:

stdbuf -oL command > output

这将stdout完全禁用缓冲:

stdbuf -o0 command > output

aaarghhh ...我的Ubuntu仅具有7.4 coreutils ... :(
Calmarius

@ Calmarius:编译coreutils应该很容易。只需从ftp.gnu.org/gnu/coreutils中获取一个新版本,然后进行操作即可。这是标准./configure && make票价。您甚至不必在事后安装它,只需使用stdbuf二进制off即可src/
爱德华多·伊万内克

双弓。我需要在旧的centos发行版和OSX以及Ubuntu上使用。
edk750


有没有办法在已知PID的情况下强制外部管道/ printf缓冲区运行已运行的进程?
6

9

您可以使用以下script命令将行缓冲输出输出到文件:

stty -echo -onlcr   # avoid added \r in output
script -q /dev/null batch_process | tee output.log        # Mac OS X, FreeBSD
script -q -c "batch_process" /dev/null | tee output.log   # Linux
stty echo onlcr

-1,因为:a)与接受的答案不同,如果要在后台运行该命令将不起作用(如果至少在我的Linux机器上batch_process追加&了上述命令,则该命令会立即终止而不完成)就像一个非常普通的用例,并且b)此处没有关于这种咒语如何工作的解释。
Mark Amery

8

在Ubuntu上,unbuffer程序(来自expect-dev)包对我有用。赶紧跑:

unbuffer your_command

并且不会缓冲它。


6

我发现的最简单的解决方案(不需要安装任何第三方软件包)在Unix&Linux站点的类似线程中提到:使用script命令。它很旧,可能已经安装了。

$ script -q /dev/null long_running_command | print_progress       # FreeBSD, Mac OS X
$ script -q -c "long_running_command" /dev/null | print_progress  # Linux

请注意,script命令的第一个文件名参数是要写入的日志文件。如果仅运行script -q your_command,则将覆盖缩进以与日志文件一起运行的命令。man script在尝试之前,请先检查一下以确保安全。


4

尝试script命令;如果您的系统有此文件,它将以文件名作为参数,所有转储到stdout的文本都将复制到该文件中。当安装程序需要交互时,这非常有用。


我知道'script -a out.txt'技巧。我想知道是否还有其他方法可以使写入过程不缓冲。
James Dean

3

就我个人而言,我更希望通过管道传递要检查的命令的输出tee

script记录了太多的信息,包括按键的时间以及很多不可打印的字符。什么tee节省是我更可读。


我还将在命令行中添加“ | less”。
HUB

4
我很确定这tee也会受到缓冲的影响。从find命令分割输出时,我经常仍然会在tee上显示部分行。
麦哲伦

2

将输出重定向到文件中,并使用tail -f命令跟随文件。

编辑

如果仍然遭受缓冲,请使用syslog工具(通常是无缓冲的)。如果批处理过程是作为Shell脚本运行的,则可以使用logger命令执行此操作。如果批处理作业以脚本语言运行,则无论如何应该有一个日志记录工具。


3
这是我现在要做的,但是该过程会缓冲对文件的写入,而这正是我要避免的事情。
James Dean

查看我的修改以获取更新的建议。
wolfgangsz

1
由于明显的原因,这不起作用。到底谁会给出This answer is useful无效的答案呢?
cnst

1

您可以使用tee命令,只是魔术!

someCommand | tee logFile.log同时显示在控制台中并写入日志文件。


不起作用 tee不会停止任何缓冲。
cnst

1
@cnst有效地,它tee不会避免一些缓冲,而只会让您看一下输出是什么。这就是@JamesDean想要的(因为我没有理解他的问题),但是我认为这里的缓冲并不是真正的问题。如果您有更多详细信息,请告诉我。

他想查看输出,但没有得到任何输出(以无缓冲的方式),但是您建议使用它tee来更好地查看未得到的输出?
cnst

1
我如何使用红色@JamesDean问题:“我将输出重定向到文件'> out.txt'”对我而言意味着没有控制台输出,请等待过程完成,同时重定向整个输出。使用时,>您在控制台上看不到任何东西。我猜@JamesDean使用“缓冲”一词来形容这一点。我将在他的问题上发表评论,让他多说一些他想要的东西。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.