2013-04-22 64 views
2

我在我的C++应用程序中使用库,并试图捕获文件中的所有输出。我试图重定向错误输出到标准输出,然后标准输出到一个文件中,像这样:如何识别在Linux的屏幕上打印什么?

./a.out 2>&1 > out.txt 

这抓住了我的应用程序几乎一切,但仍有与我使用的库在控制台上的一些输出。我的问题是:

  • 除了stdout/stderr之外还有什么? (除标准输入)
  • 如果有,我怎么能识别这些在我的情况?
  • 然后如何将这些重定向到同一个文件?

注:如果某人是熟悉的,库称为SystemC(它是一个事件驱动仿真库/上C++的顶部主要是系统/硬件设计语言)。

回答

2

您必须在任何流到流重定向之前设置输出文件,否则bash无法检测要输出的文件名。在你的情况下,你可以看到stderr输出。

参见bash redirections参考手册。

解决方案:

./a.out >out.txt 2>&1 

或者只是:

./a.out &>out.txt 
+0

嗯,工作到一定程度(+1),但仍然有一些输出在我的屏幕上。 – none 2013-04-22 13:08:15

+0

屏幕上还剩下什么输出? – James 2013-04-22 14:22:21

+0

@ Kells1986一些错误消息,如'端口未绑定' – none 2013-04-22 14:57:00

2

嗯,好我认为可能发生的是,你的程序打印到控制终端。一种可能是让你的程序作为没有控制终端的守护进程运行。我有一个C函数,我打电话把我的代码变成一个守护进程,我从一本叫做The Linux Programming Interface的书中得到了这个,我强烈推荐它。

#define BD_NO_CHDIR 01 /* Don't chdir("/") */ 
#define BD_NO_CLOSE_FILES 02 /* Don't close all open files */ 
#define BD_NO_REOPEN_STD_FDS 04 /* Don't reopen stdin, stdout, and 
       stderr to /dev/null */ 
#define BD_NO_UMASK0 010 /* Don't do a umask(0) */ 
#define BD_MAX_CLOSE 8192 /* Maximum file descriptors to close if 
      sysconf(_SC_OPEN_MAX) is indeterminate */ 


int becomeDaemon(int flags){ 

    int maxfd, fd, new_stdout; 
    switch (fork()) { /* Become background process */ 
    case -1: return -1; 
    case 0: break; /* Child falls through... */ 
    default: _exit(EXIT_SUCCESS); /* while parent terminates */ 
    } 
    if (setsid() == -1) /* Become leader of new session */ 
    return -1; 
    switch (fork()) { /* Ensure we are not session leader */ 
    case -1: return -1; 
    case 0: break; 
    default: _exit(EXIT_SUCCESS); 
    } 

    if (!(flags & BD_NO_UMASK0)) 
    umask(0); /* Clear file mode creation mask */ 
if (!(flags & BD_NO_CHDIR)) 
    chdir("/"); /* Change to root directory */ 
if (!(flags & BD_NO_CLOSE_FILES)) { /* Close all open files */ 
    maxfd = sysconf(_SC_OPEN_MAX); 
    if (maxfd == -1) /* Limit is indeterminate... */ 
    maxfd = BD_MAX_CLOSE; /* so take a guess */ 
    for (fd = 0; fd < maxfd; fd++) 
    close(fd); 
} 


if (!(flags & BD_NO_REOPEN_STD_FDS)) { 

    /* 
    STDIN = 0 
    STDOUT = 1 
    STDERR = 2 
    */ 

    close(0); /* Reopen standard fd's to /dev/null */ 
    fd = open("/dev/null", O_RDWR); 
    if (fd != 0) /* 'fd' should be 0 */ 
    return -1; 
    if (dup2(0, 1) != 1) 
    return -1; 
    if (dup2(0, 2) != 2) 
    return -1; 
    } 



return 0; 
} 

现在我想你可以行open("/dev/null", O_RDWR)改变open("/home/you/output.txt", O_RDWR)并将输出重定向那里。当然,你不能直接从终端输入你的程序,但是从你得到的错误信息的声音,我认为你反正使用套接字,所以可以写一个客户端来为你做这件事如果有必要。

希望有所帮助。

+0

对于我有的一些应用程序,我不允许更改源代码。即使我可以,这看起来比我能处理的更复杂,所以我宁愿不敢尝试。我想我希望有一个更简单的解决方案,但是无论如何感谢。+1 – none 2013-04-22 20:08:58