如何在C语言中确定stdout指向哪里?

3
我希望能够判断我的程序的标准输出是否被重定向到文件/设备,或者是否仍然正常打印在屏幕上。如何在C语言中实现这一点? 更新1:从评论中得知,这似乎取决于系统。如果是这样,那么如何在符合posix标准的系统中实现这一点?

3
据我所知,你无法做到这一点,因为它由内核处理。 - Avery3R
1
但是如果你编写通用工具,请不要像40年前的ls那样基于这个条件进行任何魔法操作。请阅读Rob Pike的《Unix环境编程》获取详细信息。 - Roland Illig
1
@Roland Illig:在我看来,这里有一个有用的用例:当连接到TTY时默认进行彩色输出,但连接到文件时不输出转义序列。当然,还应该提供命令行开关来强制打开和关闭颜色。 - DarkDust
5个回答

5

也许是 isatty(stdout)

编辑:正如Roland和tripleee所建议的那样,更好的答案是isatty(STDOUT_FILENO)


2
该方法仅适用于类POSIX实现。 - Roland Illig
1
带有前导下划线的 _isatty() 是 ISO C。 - Joseph Quinsey
@Joseph:绝对不是。ISO C没有“tty”的概念,更别提这样的函数了。而且,isatty(1)可以很好地工作(STDOUT_FILENO根据定义为1,所有shell程序员都非常清楚)。 - R.. GitHub STOP HELPING ICE
@Steve,@R.:你们说得对,我的评论是错误的。我被MSDN的isatty...误导了。这个POSIX函数已经被弃用了。请使用符合ISO C++标准的_isatty - Joseph Quinsey

3
我很抱歉,至少在标准C中无法以平台无关的方式实现。标准输入/输出的理念是C将从一个标准位置执行IO操作。这个标准位置可能是终端或文件等任何其他位置,这不是C所考虑的因素。因此,您无法检测当前使用的是哪种标准IO。如果接受平台特定解决方案,则可以参考其他答案(并相应地编辑问题)。

1
那也是平台特定的,而不是C语言标准的一部分。如果我说错了,请纠正我。 - taskinoor
@Peter Lawrey,这两个的意思有区别吗?我感到困惑。 - taskinoor
1
我假设“请让我正确”是另一种语言中的翻译表达(在谷歌上有大约60K个匹配项,因此它在某些地方应该相当常见)。“请纠正我”是更广泛使用的表达方式,在谷歌上有大约13,700K个匹配项。 - Peter Lawrey
1
@taskinoor,可能不是字面意义上的,但据我所知,在英语中没有看到过这个习语。 - Prof. Falken
@Peter Lawrey和Amigable Clark Kant,非常感谢。从现在开始我会使用“请纠正我”:-)。 - taskinoor
它的意思很清楚,通常我不会在这种事情上过于追求完美,但是它的意思是关于成为最“正确”的,这可能会给人留下错误的印象,即你对正确性的重视程度。 ;) - Peter Lawrey

3

查找 isatty 函数,以及更一般的 fileno 函数。


2

如果可以使用Linux特定的解决方案,您可以检查进程下的符号链接,位于/proc目录下。例如:

$ exec 3>/dev/null
$ ls -l /proc/$$/fd
total 0
lrwx------ 1 root root 64 Sep 12 03:28 0 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 12 03:29 1 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 12 03:29 2 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 12 03:29 255 -> /dev/pts/1
l-wx------ 1 root root 64 Sep 12 03:29 3 -> /dev/null

0

你可能想要查看这个:

http://www.cplusplus.com/reference/clibrary/cstdio/freopen/

我在引用链接中的内容:
freopen

Reopen stream with different file or mode
freopen first tries to close any file already associated with the stream given as third parameter and disassociates it.
Then, whether that stream was successfuly closed or not, freopen opens the file whose name is passed in the first parameter, filename, and associates it with the specified stream just as fopen would do using the mode value specified as the second parameter.
This function is specially useful for redirecting predefined streams like stdin, stdout and stderr to specific files.

虽然我不确定这是否会帮助您首先找出它指向的内容。


1
这如何告诉你是否连接到TTY? - DarkDust

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接