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

我有一个 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在任何输出之前完全禁用缓冲。

https://stackoverflow.com/questions/52534629/

相关文章:

c# - 在 Linux 上开发 C#

shell - 如何在后台运行命令并且没有输出?

python - Ruby 相当于 virtualenv?

python - python中的assertEquals与assertEqual

for-loop - 检测 'for'循环中最后一个元素的pythonic方法是什么?

linux - 如何在不停止的情况下在 Docker 容器中运行 Nginx?

c - Linux 中的 PATH_MAX 定义在哪里?

python - 查找列表中最常见的元素

python - 有没有类似 RStudio for Python 的东西?

linux - 如何指定编辑器来打开 crontab 文件? "export EDITOR=vi"不