shell – 我可以创建自己的输出流,它不同于stdout和stderr吗?
unistd.h的UNIX手册页说明:
The following symbolic constants are defined for file streams: STDIN_FILENO File number of stdin. It is 0. STDOUT_FILENO File number of stdout. It is 1. STDERR_FILENO File number of stderr. It is 2. 抓住我的所有头文件,我发现这是真的. [/usr]grep -r "STDIN_FILENO" include include/unistd.h:#define STDIN_FILENO 0 /* Standard input. */ [/usr] grep -r "STDOUT_FILENO" include include/unistd.h:#define STDOUT_FILENO 1 /* Standard output. */ [/usr]grep -r "STDERR_FILENO" include include/boost/asio/detail/impl/handler_tracking.ipp: ::write(STDERR_FILENO,line,length); include/unistd.h:#define STDERR_FILENO 2 /* Standard error output. */ 即使它们被定义,它们似乎永远不会被我的机器上的任何其他std头文件使用.我觉得很奇怪.也许0,1和2在别处使用而不是定义的宏.这些宏只是作为流的配置指示而引用.? 无论如何,我们可以通过这样做捕获shell中的特定输出流: ./program 1> stdout.txt ./program 2> stderr.txt ./program > both.txt 2>&1 我想创建自己的输出流,并通过这样做捕获它: ./program 3> mine.txt 我尝试搜索unistd.h和< iostream>所包含的其他文件.看看std :: cout和std :: cerr是如何工作的,但正如你可能想象的那样,我迷失了方向. 我更感兴趣的是你是否可以做到这一点,而不是它是否是一个好主意. 解决方法
子进程继承了打开的文件描述符.操作系统负责将进程与三个标准流连接,但您可以自由地执行任意数量的
open() ,然后是
exec() (最好是在之前的
fork() 之后).然后,孩子可以扫描打开的文件描述符列表(在/ proc / self / fd /中)或以某种方式“知道”使用哪些描述符.
这是一个用C编写的小例子. #include <errno.h> /* errno */ #include <stdio.h> /* atoi,fprintf */ #include <stdlib.h> /* EXIT_SUCCESS,EXIT_FAILURE */ #include <string.h> /* strerror,strlen */ #include <unistd.h> /* write */ static const char *const message = "hello,worldn"; int main(int argc,char * * argv) { int fd; int i; for (i = 1; i < argc; ++i) { fd = atoi(argv[i]); if (write(fd,message,strlen(message)) < 0) { fprintf(stderr,"error: cannot write to fd %d: %sn",fd,strerror(errno)); return EXIT_FAILURE; } } return EXIT_SUCCESS; } 程序的调用者负责打开程序应该写入的任何文件描述符,并通过其命令行参数告诉它. 为了传递连接到文件redir的打开文件描述符3,我们可以使用shell的 $exec 3>redir ./a.out 3 这将在子进程退出后关闭当前shell,因此您可能希望在子shell中尝试它: $sh -c 'exec 3>redir ./a.out 3' 或者,也可以不使用exec,而是使用重定向语法@ bmargulies.在这里,我们写入标准错误输出(2),以及文件描述符3和4,我们将3重定向到标准输出(1)和4重定向到文件redir. $./a.out 2 3 4 3>&1 4>redir hello,world hello,world $cat redir hello,world 这种文件描述符的继承在服务器进程中大量使用,这些服务器进程允许其(非特权的)子进程拥有文件描述符来记录文件, 不幸的是,在exec()unt子进程之前忘记关闭文件描述符是一个常见的错误,可能与安全相关.有一个Valgrind模块来检查这个. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |