我正在尝试了解标准流在 Linux 中的工作方式,特别是我如何使用 tail 之类的东西直接从我的终端捕获说 stdout
。由于 Linux 中的一切都是文件,难道不能简单地执行 tail -f/dev/stdout
吗?
所以为了测试这个,我写了一个简单的程序:
int main(int argc, char * argv[]) {
while (1) {
printf("This takes advantage of stdout\n");
sleep(1);
}
return 0;
}
然后在一个单独的终端中我执行了一个tail -f stdout
,但没有打印任何内容。我做错了什么吗?
最佳答案
每个process有自己的 stdout .所以你需要捕获一些正在运行的进程的标准输出。通常的方法是制作一个 pipeline , 但你也可以 redirect一些文件的标准输出。
了解更多关于 tee(1) 的信息.阅读一些 bash scripting tutorial
典型的用法可能是通过 batch(1)和一个 here document ;我经常这样做
batch << EOJ
make >& _make.out
EOJ
>&
是一个 bash -ism 或 zsh -ism 重定向标准输出和标准错误。
然后在单独的终端中 - 或者甚至在同一个终端中,在上面的 batch
序列之后 - (在相同的当前目录中)
tail -f _make.out
这使我能够看到例如一个持久的编译(当然我可以用 Ctrl C 和 tail -f
命令中断而不损害编译)。 YMMV。
另请阅读 advanced bash scripting guide
实际上,/dev/stdout
(注意 stdout
本身对 shell 没有任何特殊意义)是一个 symlink到 /proc/self/fd/1
。阅读proc(5)
顺便说一句,在你的 C 代码中,养成调用 fflush(3) 的习惯。在任何重要的系统调用之前,例如 sleep
或 fork
(您的代码不需要它,因为 terminal 上的 stdout 是 < em>line 缓冲,但当 stdout 不是 tty 时缓冲可能不同)。阅读stdout(3) .终端是奇怪的野兽,请阅读 tty demystified
附录
要在 C 或 C++ 代码中测试 stdout
是否是终端,请使用 isatty(3) ,即
if (isatty(STDOUT_FILENO))
stdout_is_a_terminal();
注意 stdout 可以是管道或文件(当然上面的测试会失败)。
要写入终端,请使用/dev/tty
(参见tty(4))。要在控制台上写入,请使用 /dev/console
(请参阅 console(4) ...)。对于系统日志记录,了解 syslog(3)和例如rsyslogd(8) .
关于c - 如何跟踪标准输出或任何标准流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23762812/