Linux Shell 重定向分为两种,一种输入重定向,一种是输出重定向。其实输入输出方向就是数据的流动方向:
- 输入方向:就是数据从哪里流向程序。数据默认从键盘流向程序,如果改变了它的方向,数据就从其它地方流入,这就是输入重定向。
- 输出方向:就是数据从程序流向哪里。数据默认从程序流向显示器,如果改变了它的方向,数据就流向其它地方,这就是输出重定向。
在 Linux 中,标准输入设备指的是键盘,标准输出设备指的是显示器。
文件描述符
Linux 中一切皆文件,包括标准输入设备(键盘)和标准输出设备(显示器)在内的所有计算机硬件都是文件。
为了表示和区分已经打开的文件,Linux 会给每个文件分配一个 ID,这个 ID 就是一个整数,被称为文件描述符(File Descriptor)。
stdin、stdout、stderr 默认都是打开的,在重定向的过程中,0、1、2 这三个文件描述符可以直接使用。
一、Shell输出重定向
输出重定向是指命令的结果不再输出到显示器上,而是输出到其它地方,一般是文件中。
这样做的最大好处就是把命令的结果保存起来,当我们需要的时候可以随时查询。
Bash 支持的输出重定向符号如下:
在输出重定向中,>代表的是覆盖,>>代表的是追加。
注意:
- 输出重定向的完整写法其实是 fd>file或者 fd>>file,其中 fd 表示文件描述符,如果不写,默认为 1(一般都省略不写),也就是标准输出文件。
- fd和>之间不能有空格,否则 Shell 会解析失败;>和file之间的空格可有可无。为了保持一致,我习惯在>两边都不加空格。
1、输出重定向
示例1:将 echo 命令的输出结果以追加的方式写入到 demo.txt 文件中。
[root@centos7 tmp]# cat test.sh
#!/bin/bash
for str in "百度一下" "http://www.baidu.com/" "shell 重定向"
do
echo $str >>demo.txt #将输入结果以追加的方式重定向到文件
done
[root@centos7 tmp]# . ./test.sh
[root@centos7 tmp]# cat demo.txt
百度一下
http://www.baidu.com/
shell 重定向
示例2:将ls -l命令的输出结果以覆盖的方式重定向到 demo.txt 文件中。
[root@centos7 tmp]# ls -al > demo.txt
[root@centos7 tmp]# cat demo.txt
总用量 8
drwxrwxrwt. 16 root root 4096 3月 3 12:28 .
dr-xr-xr-x. 18 root root 277 1月 13 2020 ..
-rw-r--r-- 1 root root 0 3月 3 12:29 demo.txt
drwxrwxrwt. 2 root root 6 12月 1 2019 .font-unix
drwxrwxrwt. 2 root root 6 12月 1 2019 .ICE-unix
drwx------ 3 root root 17 2月 27 19:57 systemd-private-01c0359be41942aab784912371f5fcb3-chronyd.service-pRrdTO
drwx------ 3 root root 17 2月 21 21:02 systemd-private-2d952048e02047f29f26d09bae616d88-chronyd.service-h5EZOo
drwx------ 3 root root 17 2月 25 14:17 systemd-private-7ddedc75621a4db691dac9a29649e990-chronyd.service-jWYilL
drwx------ 3 root root 17 3月 3 12:21 systemd-private-dc9b832f5db048d5bccf835dd334075e-chronyd.service-kqZuRO
drwx------ 3 root root 17 2月 23 20:47 systemd-private-e2f2da87a7e945868423581f4b4e575a-chronyd.service-OebGxC
-rw-r--r-- 1 root root 168 3月 3 12:27 test.sh
drwxrwxrwt. 2 root root 6 12月 1 2019 .Test-unix
drwx------ 2 root root 6 2月 27 19:57 vmware-root_8419-1688474274
drwx------ 2 root root 6 3月 3 12:21 vmware-root_8605-1948525539
drwx------ 2 root root 6 2月 25 14:17 vmware-root_8710-2857962208
drwx------ 2 root root 6 2月 23 20:47 vmware-root_8739-3844444291
drwxrwxrwt. 2 root root 6 12月 1 2019 .X11-unix
drwxrwxrwt. 2 root root 6 12月 1 2019 .XIM-unix
[root@centos7 tmp]#
2、错误输出重定向
示例:错误输出重定向举例
命令正确执行是没有错误信息的,我们必须刻意地让命令执行出错,如下所示:
[root@centos7 tmp]# ls java 2> err.log
[root@centos7 tmp]# cat err.log
ls: 无法访问java: 没有那个文件或目录
[root@centos7 tmp]# ls java 2>> err.log
[root@centos7 tmp]# cat err.log
ls: 无法访问java: 没有那个文件或目录
ls: 无法访问java: 没有那个文件或目录
3、正确输出和错误信息同时保存
示例:把正确结果和错误信息都保存到不同文件中。
[root@centos7 tmp]# ls -l >>info.log 2>>error.log
[root@centos7 tmp]# ls java >>info.log 2>>error.log
[root@centos7 tmp]# cat info.log
总用量 12
-rw-r--r-- 1 root root 1362 3月 3 12:29 demo.txt
-rw-r--r-- 1 root root 100 3月 3 12:30 err.log
-rw-r--r-- 1 root root 0 3月 3 12:33 error.log
-rw-r--r-- 1 root root 0 3月 3 12:33 info.log
drwx------ 3 root root 17 2月 27 19:57 systemd-private-01c0359be41942aab784912371f5fcb3-chronyd.service-pRrdTO
drwx------ 3 root root 17 2月 21 21:02 systemd-private-2d952048e02047f29f26d09bae616d88-chronyd.service-h5EZOo
drwx------ 3 root root 17 2月 25 14:17 systemd-private-7ddedc75621a4db691dac9a29649e990-chronyd.service-jWYilL
drwx------ 3 root root 17 3月 3 12:21 systemd-private-dc9b832f5db048d5bccf835dd334075e-chronyd.service-kqZuRO
drwx------ 3 root root 17 2月 23 20:47 systemd-private-e2f2da87a7e945868423581f4b4e575a-chronyd.service-OebGxC
-rw-r--r-- 1 root root 168 3月 3 12:27 test.sh
drwx------ 2 root root 6 2月 27 19:57 vmware-root_8419-1688474274
drwx------ 2 root root 6 3月 3 12:21 vmware-root_8605-1948525539
drwx------ 2 root root 6 2月 25 14:17 vmware-root_8710-2857962208
drwx------ 2 root root 6 2月 23 20:47 vmware-root_8739-3844444291
[root@centos7 tmp]# cat error.log
ls: 无法访问java: 没有那个文件或目录
4、/dev/null文件
如果希望执行某个命令,你既不想把命令的输出结果保存到文件,又不想输出在屏幕上显示,干扰命令的执行,那么你把命令的所有结果重定向到 /dev/null 文件中。
command > /dev/null
可以把 /dev/null 当成 Linux 系统的垃圾箱,任何放入垃圾箱的数据都会被丢弃,不能恢复。
示例:
[root@centos7 tmp]# ls -l &>/dev/null
[root@centos7 tmp]#
二、Shell输入重定向
输入重定向就是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件作为命令的输入。
Bash 支持的输出重定向符号如下:
和输出重定向类似,输入重定向的完整写法是fd<file,其中 fd 表示文件描述符,如果不写,默认为 0(一般都省略不写),也就是标准输入文件。
1、输入重定向
示例:逐行读取文件内容。
[root@centos7 tmp]# cat test2.sh
#!/bin/bash
while read str; do
echo $str
done <demo.txt
[root@centos7 tmp]# . ./test2.sh
百度一下
http://www.baidu.com/
shell 重定向
[root@centos7 tmp]#
2、分界符作为命令输入的结束标志
分界符可以自由定义,只要再碰到相同的分界符,两个分界符之间的内容将作为命令的输入(不包括分界符本身)。
此处我们使用输入重定向符号<<,这个符号的作用是使用特定的分界符作为命令输入的结束标志,而不使用 Ctrl+D 键。
示例:统计用户在终端输入的文本的行数。
[root@centos7 tmp]# wc -l <<END
> 1234
> asdf
> www
> baidu
> sss
> END
5
[root@centos7 tmp]#
wc 命令会一直等待用输入,直到遇见分界符 END 才结束读取。
– 求知若饥,虚心若愚。