如何尾标节或任何标准流?

ewo*_*ers 0 c linux terminal file-io stdout

我试图理解标准流如何在Linux中工作,特别是我可以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;
}
Run Code Online (Sandbox Code Playgroud)

然后在一个单独的终端我做了一个tail -f stdout,但没有打印.难道我做错了什么?

Bas*_*tch 6

每个进程都有自己的 标准输出.因此,您需要捕获某些正在运行的进程的标准输出.通常的方法是创建一个管道,但您也可以 stdout 重定向到某个文件.

了解有关tee(1)的更多信息.阅读一些bash脚本教程

典型的用途可能是批次(1)这里的文件 ; 我经常这样做

batch << EOJ
  make >& _make.out
EOJ
Run Code Online (Sandbox Code Playgroud)

>&是一种bash -ism或zsh -ism重定向stdout和stderr.

然后在一个单独的终端 - 或者甚至在同一个终端中,在上面的batch序列之后 - (在同一个当前目录中)

tail -f _make.out
Run Code Online (Sandbox Code Playgroud)

这使我能够看到例如持久编译的进展(当然我可以Ctrl Ctail -f不损害编译的情况下中断命令).因人而异.另请阅读高级bash脚本指南

事实上,/dev/stdout(注意,stdout单独意味着什么特殊的外壳)是一个符号链接/proc/self/fd/1.阅读程序(5)

顺便说一句,在你的C代码,采取打电话的习惯fflush(3)之前,像任何重要的系统调用sleepfork(你的代码并不需要它,因为标准输出终端线时,缓冲,但可能有不同的缓冲标准输出不是一个TTY).阅读标准输出(3).终端是奇怪的野兽,阅读tty揭秘

附加物

要在CC++代码中测试if stdout是否为终端,请使用isatty(3),即

 if (isatty(STDOUT_FILENO))
     stdout_is_a_terminal();
Run Code Online (Sandbox Code Playgroud)

请注意,stdout可能是管道或文件(当然上面的测试会失败).

要写入终端,请使用/dev/tty(参见tty(4)).要在控制台上使用/dev/console(请参阅console(4) ...).对于系统日志记录,请了解syslog(3)rsyslogd(8).