如何确定cout和cerr是否去同一个地方 有没有一种方法可以在C++中判断STD::CUT和STD::CERP是否指向同一个目的地?< /P>

如何确定cout和cerr是否去同一个地方 有没有一种方法可以在C++中判断STD::CUT和STD::CERP是否指向同一个目的地?< /P>,c++,stream,cout,C++,Stream,Cout,也就是说,我希望能够区分程序是在什么时候启动的 program或program>log2>&1或program&>log 对 程序>日志或程序2>错误或程序>日志2>错误 (用例是这样一种情况:我们希望在stdout和stderr分开时将错误信息打印到它们,但希望打印格式稍有不同的输出(而不仅仅是串联)如果他们都去同一个目的地。--是的,我知道这并不理想,也不是官方推荐的做事方式,也不应该被视为标准的做事方式。但是请相信我,我们已经花了时间仔细考虑了,对于我们的特定用例,这是最好的选择。) 出于

也就是说,我希望能够区分程序是在什么时候启动的

program
program>log2>&1
program&>log

程序>日志
程序2>错误
程序>日志2>错误

(用例是这样一种情况:我们希望在stdout和stderr分开时将错误信息打印到它们,但希望打印格式稍有不同的输出(而不仅仅是串联)如果他们都去同一个目的地。--是的,我知道这并不理想,也不是官方推荐的做事方式,也不应该被视为标准的做事方式。但是请相信我,我们已经花了时间仔细考虑了,对于我们的特定用例,这是最好的选择。)


出于我们的目的,我们可以假设程序本身没有对cout/cerr重定向做任何事情(只是典型的shell级命令行重定向),因此如果有直接查看stdout/stderr的C级功能(而不是std::cout和std::cerr流本身),这可能也行。

这是另一种情况

您真正想要实现的是:

对于我们的最终用户用例,我们希望确保指示发生了什么错误的消息最终都会出现在stderr和stdout中(因为根据我们的用户是否设置了输出重定向,他们可能会在其中一个或另一个中看到,也可能不会看到)。我们可以只在每个中打印一次(实际上是我们当前正在做的事情),但是如果stdout和stderr位于同一个位置,那么如果我们能够重新格式化以消除多余的打印,就会更清晰、更友好

考虑到这个目标,一个更干净的机制是允许用户指定他们希望错误消息去哪里。例如

the-program --error-destination "stdout"
the-program --error-destination "stderr"
the-program --error-destination "stdout,stderr"
the-program --error-destination "/tmp/errro-messages.txt"
the-program --error-destination "stdout,/tmp/errro-messages.txt"

理解到“标准输出”和“标准输出”是特殊目的地。其他任何东西都是一个文件。

如果你真的想在linux上了解,
/proc/self/fd
将显示所有信息!今天就试试ls-l/proc/self/fd


另外,如果您确定重定向窃取了您的输出,确实想向控制台发出错误,那么您可以随时将其发送到
/dev/tty
。不要费心于
/dev/stderr
,因为这只是到
/proc/self/fd/2
的链接!这样做的一个问题是,如果您的程序使用
hup
或类似工具从控制台分离,那么您显然不能使用
/dev/tty

我很好奇。你的程序为什么要关心代码< > CUT和<代码> CURR 最终写入到同一个目的地?我不知道C++标准库的方式,但是OS特定的API呢?在Windows上,您可以使用
GetStdHandle
GetFileNameFromHandle
来获取标准错误和标准输出的实际文件名;当然,Linux也有类似的功能,但程序本身并不关心——我们和我们的用户关心。对于我们的最终用户用例,我们希望确保指示发生了什么错误的消息最终都会出现在stderr和stdout中(因为根据我们的用户是否设置了输出重定向,他们可能会在其中一个或另一个中看到,也可能不会看到)。我们可以只在每个中打印一次(实际上是我们当前正在做的事情),但是如果stdout和stderr位于同一个位置,如果我们可以重新格式化以删除多余的打印,那么会更清晰、更友好。这绝对不应该由您的程序负责。将错误信息复制到所有流是一种完全的反模式,您已经发现了它不起作用的原因。我也不太理解您的用例,如果程序的调用者决定拥有冗余信息,那么就让它们去做吧。我的意思是stdout和stderr分开是有原因的,如果有人故意决定合并它们,那么你就得到了你想要的。。。尽管如此,这还是一个有趣的问题不,我想做的是在默认情况下获得格式合理的错误消息,而不需要我的最终用户跳过额外的障碍。@R.m.,这样做总是正确的。这不应妨碍您允许用户做出选择。我不妨碍添加选项以指定用户需要错误信息的位置。然而,这仍然留下了一个问题,即当他们没有指定这样一个选项时该怎么办。在这种情况下,首选行为会让我们回到原来的问题:当stdout和stderr是不同的流时,将一个内容打印到stdout和stderr,但当它们是相同的目标时,将打印一个不同格式的内容(不仅仅是串联)。@R.M。,默认行为应该是仅将错误消息打印到
stderr
/
std::cerr
。所有其他输出应转到
stdout
/
std::cout
。在代码中添加更细粒度的逻辑对我来说没有意义。虽然我在抽象的理论意义上同意我们的特定程序、特定的最终用户以及他们的特定用例,但将错误消息打印到stdout和stderr无疑是首选行为。从抽象的理论意义上讲,告诉我们的最终用户“糟糕透顶。错误消息默认为stderr。接受它并进行处理。”这在实践中并不奏效。