printf除非换行符在格式字符串中,为什么在调用后不刷新?这是POSIX的行为吗?我怎么可能printf每次都立即冲洗?
如何将stdout重定向到Python中的任意文件?
当从ssh会话中启动长时间运行的Python脚本(例如,Web应用程序)并进行后台处理,并且ssh会话关闭时,应用程序将引发IOError并在尝试写入stdout时失败.我需要找到一种方法来将应用程序和模块输出到文件而不是stdout,以防止由于IOError导致的失败.目前,我使用nohup将输出重定向到一个文件,这就完成了工作,但是我想知道是否有办法在不使用nohup的情况下完成它,出于好奇.
我已经尝试了sys.stdout = open('somefile', 'w'),但这似乎并没有阻止一些外部模块仍然输出到终端(或者sys.stdout = ...线路根本没有发射).我知道它应该使用我测试过的简单脚本,但我还没有时间在Web应用程序上进行测试.
我有一个小脚本,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)
并跟踪进度等
我只是好奇应该满足哪些条件自动刷新stdout缓冲区.
首先,我很困惑这个伪代码不会在每次迭代时打印输出:
while (1) {
printf("Any text");
sleep(1);
}
Run Code Online (Sandbox Code Playgroud)
但如果我添加换行符,它会.
经过几次实验,我发现在我的机器上stdout缓冲区被刷新:
第一个条件是完全清楚的 - 当缓冲区已满时,应该刷新它.第二个也是合理的.但为什么换行符导致潮红?其他隐含的条件是什么?
这是我的计划.
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello\n");
system("uname");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是输出.
$ gcc foo.c
$ ./a.out
Hello
Linux
Run Code Online (Sandbox Code Playgroud)
但是,如果我将程序的输出重定向到文件,我会看到输出的顺序是相反的,即Linux之前打印的顺序Hello.
$ ./a.out > out.txt
$ cat out.txt
Linux
Hello
Run Code Online (Sandbox Code Playgroud)
为什么涉及重定向时输出的顺序不同?
我尝试printf从我的汇编代码中使用,这是一个应该打印hello到标准输出的最小示例:
.section .rodata
hello:
.ascii "hello\n\0"
.section .text
.globl _start
_start:
movq $hello, %rdi # first parameter
xorl %eax, %eax # 0 - number of used vector registers
call printf
#exit
movq $60, %rax
movq $0, %rdi
syscall
Run Code Online (Sandbox Code Playgroud)
我用
gcc -nostdlib try_printf.s -o try_printf -lc
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它似乎工作:字符串hello被打印出来,退出状态是0:
XXX$ ./try_printf
hello
XXX$ echo $?
0
XXX$
Run Code Online (Sandbox Code Playgroud)
但是当我尝试捕获文本时,很明显,某些内容无法正常工作:
XXX$ output=$(./try_printf)
XXX$ echo $output
XXX$
Run Code Online (Sandbox Code Playgroud)
该变量output应具有 value hello,但为空。
我的用法有printf什么问题?
在我在 Linux 上运行的 C 程序中,它使用创建子进程system()我注意到,当我将stdout重定向到管道或文件时,子进程的输出在缓冲 I/O 函数的输出之前发送,例如printf(). 当stdout被留在终端时,输出按预期顺序排列。我将程序简化为以下示例:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("1. output from printf()\n");
system("echo '2. output from a command called using system()'");
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
stdout进入终端时的预期输出:
$ ./iobuffer
1. output from printf()
2. output from a command called using system()
Run Code Online (Sandbox Code Playgroud)
将stdout重定向到管道或文件时的输出乱序:
$ ./iobuffer | cat
2. output from a command called using system()
1. output from printf()
Run Code Online (Sandbox Code Playgroud)