1. 重定向的作用
标准输入输出重定向是将原本从标准输入读取的数据或字符串内容,以及由程序运行过程中产生的输出等信息按照我们的使用意图来定向保存到系统的非默认信息处理位置。通过标准重定向,我们可以实现信息的重复利用,使得Linux的管理更加方便。比如在使用脚本时,我们可以直接在终端中显示脚本的输出,也可以将其重定向到文件中,然后接着对脚本的输出进行后续的处理。
2. 标准文件描述符
我们都知道,在Linux系统中“一切皆是文件”,使用文件描述符来标识每个文件对象。文件描述符是一个非负整数,可以唯一标识会话中打开的文件,每个进程一次最多可以有九个文件描述符。出于特殊目的,bash shell保留了前三个文件描述符( 0 、 1 和 2 )。
文件描述符 | 缩写 | 描述 |
---|---|---|
0 | STDIN | 标准输入 |
1 | STDOUT | 标准输出 |
2 | STDERR | 标准错误 |
2.1 STDIN
STDIN文件描述符表示shell的标准输入。对终端来说,标准输入是从键盘获得的,使用“<”表示。一般情况下,Bash都是通过STDIN获得数据输入,然后在程序中进行数据处理的。比如使用cat命令时,如果后面不跟具体文件时,就会进入从STDIN输入(此处从键盘获得)获得数据:
ubuntu@localhost:~$ cat
this is a test
this is a test
或者通过另一个文件获得输入:
ubuntu@localhost:~$ cat < testfile
This is the test line.
2.2 STDOUT
STDOUT文件描述符代表shell的标准输出。一般情况下,标准输出会显示在终端显示器中,Bash的各种输出(包括shell中运行的程序和脚本)都会被定向到标准输出中,使用“>”表示。比如,我们可以将最简单的ll命令查看的文件内容重定向到文件中:
ubuntu@localhost:~$ ll > testfile
ubuntu@localhost:~$ cat testfile
total 55232
drwxr-xr-x 18 ubuntu ubuntu 4096 10月 11 22:26 ./
drwxr-xr-x 3 root root 4096 10月 2 11:01 ../
-rw------- 1 ubuntu ubuntu 287 10月 9 22:24 .bash_history
-rw-r--r-- 1 ubuntu ubuntu 220 10月 2 11:01 .bash_logout
-rw-r--r-- 1 ubuntu ubuntu 3771 10月 2 11:01 .bashrc
drwx------ 12 ubuntu ubuntu 4096 10月 8 19:52 .cache/
drwx------ 3 ubuntu ubuntu 4096 10月 2 11:18 .compiz/
2.3 STDERR
在Bash中使用STDERR来处理错误消息,程序或运行脚本出错时产生的错误信息都会由STDERR来接收,然后再进一步将其输出到终端或保存到日志文件中,使用“2>”表示。默认情况下, STDERR 和 STDOUT都会输出到终端窗口中。例如,使用ls命令查看一个不存在的文件时会报错,我们可以将错误信息重定向到文件中:
ubuntu@localhost:~$ ls badfile 2> error.txt
ubuntu@localhost:~$ cat error.txt
ls: cannot access 'badfile': No such file or directory
3. 常见的重定向符号
符号 | 说明 |
---|---|
> | 输出重定向 |
>> | 追加重定向 |
1> | 输出重定向 |
2> | 错误重定向 |
2>> | 错误追加重定向 |
< | 输入重定向 |
<< | 内联输入重定向 |
&> | 输出和错误重定向到同一文件中 |
&>> | 输出和错误追加重定向到同一文件中 |
tee | 同时输出到终端和指定的文件中 |
4. 重定向举例
-
从键盘操作实现输入重定向
ubuntu@localhost:~$ cat >testfile1 <<EOF > hello ubuntu > linux > EOF ubuntu@localhost:~$ cat testfile1 hello ubuntu linux
注:EOF为结束符
-
从文件输入重定向
ubuntu@localhost:~$ cat < testfile1 hello ubuntu linux
-
标准输出重定向到文件
ubuntu@localhost:~$ date > datefile ubuntu@localhost:~$ cat datefile 2019年 10月 12日 星期六 19:48:39 CST
-
标准错误重定向到文件
ubuntu@localhost:~$ ll badfile 2> errorfile ubuntu@localhost:~$ cat errorfile ls: cannot access 'badfile': No such file or directory
-
在原有文件的最后追加定向新内容
ubuntu@localhost:~$ echo "Test2 IO" >> testfile1 ubuntu@localhost:~$ cat testfile1 hello ubuntu linux Test2 IO
-
标准错误追加重定向
ubuntu@localhost:~$ nadsf 2>> errorfile ubuntu@localhost:~$ cat errorfile ls: cannot access 'badfile': No such file or directory nadsf: command not found
-
标准输出和错误输出到同一文件中
ubuntu@localhost:~$ ll datefile badfile &> errorfile2 ubuntu@localhost:~$ cat errorfile2 ls: cannot access 'badfile': No such file or directory -rw-rw-r-- 1 ubuntu ubuntu 43 10月 12 19:48 datefile
-
标准输出和错误输出到不同文件中
ubuntu@localhost:~$ ll datefile badfile 1> log.txt 2> errorfile3 ubuntu@localhost:~$ cat log.txt -rw-rw-r-- 1 ubuntu ubuntu 43 10月 12 19:48 datefile ubuntu@localhost:~$ cat errorfile3 ls: cannot access 'badfile': No such file or directory
-
将信息同时输出到终端和文件
ubuntu@localhost:~$ ll testfile* | tee log2.txt -rw-rw-r-- 1 ubuntu ubuntu 1986 10月 11 22:26 testfile -rw-rw-r-- 1 ubuntu ubuntu 28 10月 12 20:12 testfile1 ubuntu@localhost:~$ cat log2.txt -rw-rw-r-- 1 ubuntu ubuntu 1986 10月 11 22:26 testfile -rw-rw-r-- 1 ubuntu ubuntu 28 10月 12 20:12 testfile1
5. 应用案例
-
实际使用中,将find命令查找得到的文件名保存到文件中
ubuntu@localhost:~$ find /home/ubuntu/ -name 'test*' >& find_file ubuntu@localhost:~$ cat find_file /home/ubuntu/testfile /home/ubuntu/testfile1
-
执行脚本过程中不希望由任何输出时,重定向到/dev/null中
ubuntu@localhost:~$ sudo apt install ssh -y >/dev/null ubuntu@localhost:~$ ll . >/dev/null ubuntu@localhost:~$
-
使用sed命令修改文件内容
ubuntu@localhost:~$ cat /etc/resolv.conf # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN nameserver 127.0.1.1 search localdomain ubuntu@localhost:~$ sudo sed -i 's/nameserver 127.0.1.1/nameserver 114.114.114.114/' /etc/resolv.conf ubuntu@localhost:~$ cat /etc/resolv.conf # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN nameserver 114.114.114.114 search localdomain