c - 将输出重定向到文件时 printf() 和 system() 的结果顺序错误

标签 c linux printf child-process io-redirection

我有一个 C 程序,可以编译为名为 myprogram 的可执行文件。这是它的主要功能:

int main(int argc, char ** argv) {
  printf("this is a test message.\n");
  system("ls");

  return 0;
}

当我在 Linux shell 中运行 myprogram> output.txt 然后检查 output.txt 时,我看到上面列出的 ls 的输出“这是一条测试消息。”

我觉得应该反过来。为什么会发生这种情况,我该怎么做才能使“这是一条测试消息”出现在 output.txt 的顶部?

如果重要的话,我对 C 和命令行都是新手。

最佳答案

当连接到终端时,默认输出到 stdoutline-buffered。也就是说,当缓冲区已满或添加换行符时,缓冲区会被刷新。

但是,如果 stdout 没有连接到终端,例如将程序的输出重定向到文件时会发生什么,然后 stdout 变为 完全缓冲。这意味着缓冲区将在已满或显式刷新(程序退出时发生)时被刷新并实际写入。

这意味着从您的代码开始的单独进程的输出(就像您调用 system 时发生的情况一样)很可能首先被写入,因为该进程的缓冲区将在那个时候被刷新进程结束,在你自己的进程之前。

使用重定向(或管道)时会发生什么:

  1. 您的 printf 调用将写入 stdout 缓冲区。
  2. system 函数启动一个新进程,该进程写入自己的缓冲区。
  3. 当外部进程(由您的 system 调用启动)退出时,其缓冲区被刷新和写入。您自己的进程中自己的缓冲区不会被触及。
  4. 您自己的进程结束,您的 stdout 缓冲区被刷新和写入。

要以“正确的”(或至少预期的)顺序获得输出,请调用 fflush在调用 system 之前,显式刷新 stdout,或调用 setbuf在任何输出之前完全禁用缓冲。

关于c - 将输出重定向到文件时 printf() 和 system() 的结果顺序错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52534629/

相关文章:

c - fprintf 语句中的\b 转义序列有问题..?

c - bool 的 printf 格式说明符是什么?

c - argv[n] 是可写的吗?

c - 在 C 中使用正则表达式时,\d 不起作用,但 [0-9] 起作用

linux - 程序集:试图写入文件,但文本附加到文件名

c - 带有左对齐标志的 printf() 位置参数

python - 尝试将 python 片段导入 C/C++(PI spigot 算法)

c++ - sem_timedwait 与 CLOCK_MONOTONIC_RAW/CLOCK_MONOTONIC

Java 图形只覆盖新形状?

mysql - 错误 : token "@" is not valid in preprocessor expressions