Bash重定向的本质:对文件描述符的操作。当启动bash时,它打开了三个文件描述符,标准输入stdin(文件描述符0),标准输出stdout(文件描述符1),标准错误输出stderr(文件描述符2)。你可以打开更多的文件描述符(3,4,5。。。)也可以关闭这些描述符。你还可以拷贝文件描述符,并对文件描述符进行读写。 打开的文件描述符一直指向一个文件。通常来说,bash启动时打开的文件描述符(stdin,stdout,stderr)指向终端。 假设你的终端是 /dev/tty0,下图是你刚打开终端时文件描述符的状态:
当bash执行一个命令程序时,它从父进程fork出一个子进程(man 2 fork),并继承了父进程里所有的文件描述符。然后设置你所指定的重定向,最后执行命令(man 3 exec)。 理解重定向的要点是:当重定向发生时,文件描述符是怎么改变的,下面每条命令都配有图示,帮助理解。
重定向一个命令的标准输出到文件 $ command > filename # 或 command 1> filename bash打开文件并替换文件描述符1(1代表标准输出stdout),所以在终端中的输出的内容才会被重定向到文件中。
例如: $ ls > file_list
重定向一个命令的标准输出到文件 $ command 2> file 2代表标准错误输出。stderr替换为文件描述符,如图:
重定向一个命令的标准输出和标准错误输出到文件 $ command &> file
从上图可以看到两个文件描述符指向同一个文件。
另一种方法: $ command > file 2>&1 第一步:重定向标准输出(stdout)到文件。第二步:复制stdout文件描述符为stderr文件描述符。这样1和2文件描述符都指向了file文件。 如果写成这样: $ command 2>&1 >file 注意:这是错的,它并不和上面等同。实际上它只重定向了stdout。看下面图示: 初始状态:
重定向的处理流程是从左向右。它看到了2>&1,复制stdout给stderr,文件描述符为:
下面重定向 >file:
丢弃命令的标准输出 $ command > /dev/null # $ command >/dev/null 2>&1
重定向文件内容到标准输入 $ command <file
例如: $ read -r line < file 更多文件操作看 Linux Bash命令示例:文件相关。
使用自定义文件描述符 $ exec 3< filename # > 写文件 <>读写文件 打开一个文件并分配文件描述符3
像这样读文件 $ read -u 3 line
访问网络 $ exec 3<>/dev/tcp/www.baidu.com/80 $ echo -e "GET / HTTP/1.1nn" >&3 $ cat <&3
/dev/tcp/host/port 是特殊的文件,相似/dev/udp/host/port。甚至可以用/dev/tcp/host/port写一个扫描端口脚本。
一个命令的输出是另一个命令的输入 $ command1 2>&1 | command2 图示:
|