重定向
Linux 中标准的输入设备默认指的是键盘,标准输出指的是显示器,而这里的重定向也就是对输入、输出的重定向;
- 输入重定向:指的是重新指定设备来代替键盘作为新的输入设备;
- 输出重定向:指的是重新指定设备来代替显示器作为新的输出设备。
通常是用文件或命令的执行结果来代替键盘作为新的输入设备,而新的输出设备通常指的就是文件。
在 Linux 系统中,一切皆是文件,键盘和显示器等硬件都是文件,如下表:
| 设备 |
设备文件名 |
文件描述符 |
类型 |
| 键盘 |
/dev/stdin |
0 |
标准输入 |
| 显示器 |
/dev/stdout |
1 |
标准输出 |
| 显示器 |
/dev/stderr |
2 |
标准错误输出 |
从表中可以看出,键盘的设备文件名为 /dev/stdin ,显示器标准正确输入的设备文件名为 /dev/stdout,显示器标准错误输入的设备文件名为 /dev/stderr。
这些设备文件名非常不好记忆,Shell 允许我们用文件描述符来描述对应的设备,也就是用 0、1、2,分别对应键盘、正确显示器,错误显示器。
输入重定向
输入重定向所用到的符号如表所示:
| 命令符号格式 |
作用 |
| 命令 < 文件 |
将文件作为命令的输入 |
| 命令 << 分界符 |
表示从标准输入设备(键盘)中读入,直到遇到分界符才停止(读入的数据不包括分界符),这里的分界符其实就是自定义的字符串;通常分界符用的最多的是 EOF |
| 命令 < 文件 1 > 文件 2 |
将文件 1 作为命令的输入设备,该命令的执行结果输出到文件 2 中。 |
示例:
默认情况下,cat 命令会接受标准输入设备(键盘)的输入,并显示到控制台,但如果用文件代替键盘作为输入设备,那么该命令会以指定的文件作为输入设备,并将文件中的内容读取并显示到控制台。
以 /etc/passwd 文件(存储了系统中所有用户的基本信息)为例,执行如下命令:
1 2 3 4
| root@ls529hJ9gm:~# cat /etc/passwd
root@ls529hJ9gm:~# cat < /etc/passwd
|
注意,虽然执行结果相同,但第一行代表是以键盘作为输入设备,而第二行代码是以 /etc/passwd 文件作为输入设备。
示例 2:
1 2 3 4 5 6 7 8 9
| root@ls529hJ9gm:~# wc -l 11 22 2
root@ls529hJ9gm:~# wc -l < /etc/passwd 29
|
最终结果与示例 1 相同,统计出了 29 行。
输出重定向
命令的输出是输出给标准输出的,也就是输出到显示器上。而输出重定向就是命令的输出,不输出给标准输出,而是把输出的内容输出到文件中或者其他的输出设备中。
输出重定向所用到的符号如表所示:
| 命令符号格式 |
作用 |
| 命令 > 文件 |
以覆盖的方式,把命令的正确输出,输出到指定的文件或者设备当中 |
| 命令 2> 文件 |
以覆盖的方式,把命令的错误输出,输出到指定的文件或者设备当中 |
| 命令 >> 文件 |
以追加的方式,把命令的正确输出,输出到指定的文件或者设备当中 |
| 命令 2>> 文件 |
以追加的方式,把命令的错误输出,输出到指定的文件或者设备当中 |
| 命令 > 文件 2>&1 |
以覆盖的方式,把命令的正确输出和错误输出,输出到指定的文件或者设备当中 |
| 命令 >> 文件 2>>&1 |
以追加的方式,把命令的正确输出和错误输出,输出到指定的文件或者设备当中 |
| 命令 >> 文件 1 2>>文件 2 |
以追加的方式,把命令的正确输出输出到文件 1,把错误输出输出到文件 2 中 |
标准输出重定向
1 2 3 4 5 6 7 8 9
| [root@localhost ~]# pwd > abc [root@localhost ~]# cat abc /root
[root@localhost ~]# pwd >> abc [root@localhost ~]# cat abc /root /root
|
只要该命令有结果,都能够进行输出重定向。
标准错误输出重定向
1 2 3 4 5
| [root@localhost ~]# lsdgagsa 2>> abc [root@localhost ~]# cat abc /root /root -bash: lsdgagsa: command not found
|
这个 2 是文件描述符,表示标准错误输出。
1 2
| 这里需要注意的是,上边的标准正确输出和标准错误输出的重定向有一些小问题,就是我要事先知道这条命令是否报错,才能选择是使用标准正确输出还是使用标准错误输出。 这样十分不合理,我明知道命令会报错,那我直接写对不就完了。所以我们在工作中写脚本的时候,常用的输出重定向的方式是下面的方式。
|
正确输出和错误输出同时保存
有 3 种方式
方式一
命令 > 文件 2>&1:以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。
命令 >> 文件 2>&1:以追加的方式,把正确输出和错误输出都保存到同一个文件当中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| [root@localhost ~]# ls > abc 2>&1 [root@localhost ~]# cat abc anaconda-ks.cfg install.log install.log.syslog
[root@localhost ~]# lsadfgag >> abc 2>&1 [root@localhost ~]# cat abc anaconda-ks.cfg install.log install.log.syslog -bash: lsadfgag: command not found
|
方式二
命令 &> 文件:以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。
命令 &>> 文件:以追加的方式,把正确输出和错误输出都保存到同一个文件当中。(常用)
1 2 3 4 5 6 7 8 9
| [root@localhost ~]# pwd &> abc [root@localhost ~]# cat abc /root
[root@localhost ~]# lsadfgag &>> abc [root@localhost ~]# cat abc /root -bash: lsadfgag: command not found
|
方式三
命令 >> 文件 1 2>>文件 2:把正确的输出追加到文件 1 当中,把错误的输出追加到文件 2 中。(常用)
1 2 3 4 5 6
| [root@localhost ~]# pwd >> ok 2>>err [root@localhost ~]# cat ok /root [root@localhost ~]# asdasd >> ok 2>>err [root@localhost ~]# cat err -bash: asdasd: command not found
|
1
| 注意,在错误输出里,2和`>`和`>>`之间是不能有空格的
|
这里的方式是选择统一保存呢还是分开保存,全看你个人习惯。
管道符
管道符 |,也是 Shell 命令。
管道符的作用是链接多个命令,把命令 1 的结果作为命令 2 的操作对象。
1 2
| 命令格式:命令1 | 命令2 命令1的正确输出作为命令2的操作对象
|
管道符主要用于多重命令处理,前面命令的打印结果作为后面命令的输入。简单点说就是,就像工厂的流水线一样,进行完一道工序后,继续传送给下一道工序处理…
应用
举个例子,我们经常需要使用 ls -l 命令查看文件的长格式,不过在有些目录中文件众多,比如 etc/ 目录,使用 ls -l 命令显示的内容就会非常多,只能看到最后的内容,而不能看到前面输出的内容。
这时候可以使用 more 命令,more 命令可以分屏现实文件内容,而不能看到前面输出的内容。
使用管道符,将这 2 个命令链接起来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| [root@localhost ~]# ls -l /etc | more 总用量 1160 drwxr-xr-x 4 root root 4096 5月 30 11:12 acpi -rw-r--r-- 1 root root 2981 5月 30 11:09 adduser.conf -rw-r--r-- 1 root root 46 8月 29 02:49 adjtime drwxr-xr-x 3 root root 4096 5月 30 11:11 alsa drwxr-xr-x 2 root root 4096 10月 14 10:47 alternatives drwxr-xr-x 3 root root 4096 5月 30 11:13 apm drwxr-xr-x 5 root root 4096 5月 30 11:15 apparmor.d -rw-r--r-- 1 root root 73 5月 17 10:34 appstore.json drwxr-xr-x 7 root root 4096 8月 29 10:48 apt drwxr-xr-x 3 root root 4096 5月 30 11:15 avahi -rw-r--r-- 1 root root 1987 8月 4 2020 bash.bashrc -rw-r--r-- 1 root root 45 2月 12 2019 bash_completion drwxr-xr-x 2 root root 4096 8月 29 10:53 bash_completion.d -rw-r--r-- 1 root root 367 3月 17 2022 bindresvport.blacklist drwxr-xr-x 2 root root 4096 5月 30 11:15 binfmt.d drwxr-xr-x 2 root root 4096 5月 30 11:14 bluetooth drwxr-xr-x 3 root root 4096 5月 30 11:14 browser drwxr-xr-x 3 root root 4096 5月 30 11:09 ca-certificates -rw-r--r-- 1 root root 5989 5月 30 11:09 ca-certificates.conf drwxr-xr-x 2 root root 4096 5月 30 11:09 calendar drwxr-s--- 2 root dip 4096 5月 30 11:14 chatscripts drwxr-xr-x 2 root root 4096 5月 30 11:14 cracklib drwxr-xr-x 2 root root 4096 5月 30 11:14 cron.d drwxr-xr-x 2 root root 4096 5月 30 11:20 cron.daily drwxr-xr-x 2 root root 4096 5月 30 11:09 cron.hourly drwxr-xr-x 2 root root 4096 5月 30 11:09 cron.monthly -rw-r--r-- 1 root root 1042 10月 11 2019 crontab drwxr-xr-x 2 root root 4096 5月 30 11:09 cron.weekly drwxr-xr-x 2 root root 4096 5月 30 11:15 cryptsetup-initramfs --More--
|
管道符是文本流操作,管道符把前边的 ls -l 命令的结果转换成文本,然后供 more 命令分屏显示。