Shell 我可以创建自己的不同于stdout和stderr的输出流吗?
Shell 我可以创建自己的不同于stdout和stderr的输出流吗?,shell,stdout,stderr,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]gr
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
和
中包含的其他文件,看看std::cout
和std::cerr
是如何工作的,但正如你可能想象的那样,我迷路了
我更感兴趣的是你是否能做到这一点,而不是这是否是一个好主意。当你调用
open
时,它会返回一个数字。您将该数字传递给读取
和写入
。但是,您可以运行如下命令:
mycommand 3 3>bloop.txt
在mycommand中,将argv[1]转换为一个数字,并将其传递给write。打开的文件描述符由子进程继承。操作系统负责将一个进程与三个标准流连接起来,但您可以自由地执行任意数量的s,然后执行一个(最好在前一个之后)。然后,孩子可以扫描打开的文件描述符列表(在
/proc/self/fd/
中),或者以某种方式“知道”要使用哪些描述符
下面是一个用C编写的小示例
#include/*errno*/
#包括/*atoi、fprintf*/
#包括/*退出成功,退出失败*/
#包括/*strerror,斯特伦*/
#包括/*写入*/
static const char*const message=“你好,世界\n”;
int main(int argc,字符**argv)
{
int-fd;
int i;
对于(i=1;i
程序的调用方负责打开程序应该写入的任何文件描述符,并通过其命令行参数告诉它
要将连接到文件redir
的打开文件描述符3传递给它,我们可以使用shell的实用程序打开文件描述符并执行子脚本
$exec 3>重拨。/a.out 3
这将在子shell退出后关闭当前shell,因此您可能希望在子shell中尝试它:
$sh-c'exec 3>redir./a.out 3'
或者,不要使用exec
,而是使用前面提到的重定向语法@。这里,我们正在写入标准错误输出(2),以及文件描述符3和4,其中我们将3重定向到标准输出(1),将4重定向到文件redir
$。/a.out 2 3 4 3>&1 4>重拨
你好,世界
你好,世界
$cat redir
你好,世界
这种文件描述符的继承在服务器进程中被大量使用,这些进程让他们的(非特权)子进程拥有文件描述符来记录文件、监狱外的文件、TCP连接等等
不幸的是,在调用子进程之前忘记关闭文件描述符是一个常见的错误,可能与安全相关。有一个模块可以检查这一点。请查看Bash文档。文件描述符由bash从登录或终端程序继承,然后由您的程序继承。如果您使用GCC,您可能会发现它们的非标准库:
,它允许您从POSIX文件描述符创建一个std::filebuf
(从而创建一个std::fstream
),此函数的第一个参数。文件描述符(fd)