【问题标题】:How to identify what is printing on screen in linux?如何识别linux中屏幕上打印的内容?
【发布时间】:2013-04-22 12:57:01
【问题描述】:

我在我的 C++ 应用程序中使用了一个库,并试图将所有输出捕获到一个文件中。我试图将标准错误重定向到标准输出,然后将标准输出重定向到这样的文件:

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

这几乎捕获了我的应用程序中的所有内容,但控制台上仍有一些与我正在使用的库相关的输出。我的问题是:

  • 除了stdout/stderr还有什么? (标准输入除外)
  • 如果有,我该如何识别这些?
  • 然后如何将它们重定向到同一个文件?

注意:如果有人熟悉,库称为SystemC(这是一个基于 C++ 的事件驱动仿真库/语言,主要用于系统/硬件设计)。

【问题讨论】:

    标签: bash shell pipe stdout stderr


    【解决方案1】:

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

    请参阅bash redirections 参考手册。

    解决方案:

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

    或者只是:

    ./a.out &>out.txt
    

    【讨论】:

    • hmmm,这在某种程度上有效(+1),但我的屏幕上仍有一些输出。
    • 屏幕上还剩下什么输出?
    【解决方案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) 并将输出重定向到那里。当然,那么您将无法直接从终端输入到您的程序,但是从您收到的错误消息的声音来看,我认为您无论如何都在使用套接字,因此可以编写一个客户端来为您执行此操作如果有必要。

    希望对您有所帮助。

    【讨论】:

    • 对于我拥有的一些应用程序,我不允许更改源代码。即使我可以,这看起来也比我能处理的复杂,所以我不敢尝试。我想我希望有一个更简单的解决方案,但无论如何谢谢.. +1
    猜你喜欢
    • 1970-01-01
    • 2019-03-07
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多