首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将stderr输出(使用fprintf )重定向到日志文件?

如何将stderr输出(使用fprintf )重定向到日志文件?
EN

Stack Overflow用户
提问于 2020-10-21 15:00:07
回答 2查看 198关注 0票数 1

我正在做一些调试,并希望将标准错误消息重定向到一个文件;这样,它就可以在调试日志文件中查看。我确实需要从C代码中完成,而不是通过UNIX shell重定向。

我需要调试一些这样的模块。我有一组调试工具,可以写入strerr(控制台)。很容易将其包含到源中,并呈现一组舒适宏和函数,以用于调试源。

下面是一个头文件中的代码。

代码语言:javascript
运行
复制
#include <stdio.h>

#define LOGWRAPPER(tag, fmt, args...) \
  fprintf(stderr, "%s: " fmt "\n", tag, ##args)   

#define LOG_DEBUG(...) LOGWRAPPER(__VA_ARGS__)

...

...

#define LOG_DEBUG(tag, fmt, args...)                 \
  do {                                               \
    (true) ? ALOG(LOG_DEBUG, tag, fmt, ##args)       \
           : fprintf(stderr, "%s" fmt, tag, ##args); \
  } while (0)
....

最终,所有的打印都会返回到这里,这是头文件。所以我想我得做些改变

代码语言:javascript
运行
复制
#define LOGWRAPPER(tag, fmt, args...) \
  fprintf(stderr, "%s: " fmt "\n", tag, ##args)

有什么想法吗?或者我应该创建一个文件路径并插入到fprintf中?

EN

回答 2

Stack Overflow用户

发布于 2020-10-21 15:28:46

在C代码中重定向stderr的典型方法是使用dup2() (本质上)将文件描述符映射到新文件。例如,如下所示:

int f= open ("mylog.txt",O_CREAT | O_RDWR | O_APPEND,0644);dup2 (f,STDERR_FILENO);

还有其他方法--例如,您可以在stderr上使用freopen()

但是..。

如果您使用自己定义的宏来执行所有日志记录,为什么不简单地定义宏来执行完全不同的操作呢?也就是说,定义LOG_DEBUG来调用您提供函数,而不是fprintf()

我相信在这个问题上还有其他的观点,但我不喜欢使用stderr进行日常日志记录。我只想让stderr得到严重的、破坏程序的错误消息。有可能(也许)您的代码不是唯一可能写入stderr的代码--库也可能这样做。收集它们的输出并将其发送到常规调试日志可能是合适的,但也可能不是这样。我总是使用专门用于此目的的函数来执行常规日志记录。

票数 3
EN

Stack Overflow用户

发布于 2020-10-21 16:29:01

我确实需要从C代码中完成,而不是通过UNIX shell重定向。

了解shell如何实现重定向将使您对如何在自己的程序中实现重定向有必要的了解。

POSIX定义了在每个进程开始时可用的三个标准文件描述符:0= stdin,1= stdout,2= stderr

C标准库还定义了三个通过全局可用的符号公开的FILE*流,分别命名为stdinstdoutstderr,并直接对应于数字文件描述符;POSIX标准定义了一个在FILE*流上操作的名为fileno的附加函数。

归根结底,一切都归结为文件描述符。

尽管可以将现有的流freopen到新的目的地,但这通常会产生一个新的、不同的文件描述符。虽然您重新编写的FILE*流(可能通过像stderr这样的全局符号)将转到那个新位置,但它不会影响绕过C标准库函数的程序部分。因此,推荐的方法是替换filedescriptor本身,这就是syscall dup2所做的。

使用dup2,您可以获取一个现有的文件描述符,并将其复制-覆盖另一个现有的文件描述符。因此,如果您打开一个日志文件,并在文件描述符2 (=stderr)上复制它,那么它的输出将被重定向到那里。

这是shell重定向的方式,您也可以在您的程序中使用它:

代码语言:javascript
运行
复制
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
    /* replace fd=2, i.e. stderr, with a file of our choosing: */
    int fd_logfile = open("logfile.txt", O_RDWR | O_CREAT | O_APPEND, 0644);
    if( 0 <= fd_logfile ){
        dup2(fd_logfile, 2);
        close(fd_logfile);
    }
    
    /* ... */
    fprintf(stderr, "This should go to logfile.txt\n");
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64458230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档