重定向
标准输入、输出和错误
许多程序都会产生某种输出。此输出通常由两种类型。一种是程序的输出结果;也就是说,数据程序所产生的。另一种是某些状态或错误消息告诉我们程序进展如何。
如果我们查看像ls这样的命令,我们可以看到它在屏幕上显示其结果和错误消息。遵循“一切皆文件”,诸如ls之类的程序实际上将其结果保存到一个称为标准输出的特殊文件中(通常表示stdout),状态消息发送到另一个文件,称为标准错误(stderr)。
默认情况下,标准输出和标准错误都输出到屏幕上,而不保存到磁盘文件中。另外,许多程序从称为标准输入(stdin)的设备(文件)中获取输入,默认情况下已连接到键盘。
重定向标准输出
I/O重定向使我们可以重新定义标准输出的位置。重定向标准输出到另一个文件而不是屏幕,我们使用“>”or“>>”操作符重定向到文件。
[root@iZerb5rob3dcf6Z ~]# ls /usr/bin/ > stdout.txt
[root@iZerb5rob3dcf6Z ~]# less stdout.txt
....
[root@iZerb5rob3dcf6Z ~]# ls /bin/usr > stdout.txt
ls: 无法访问/bin/usr: 没有那个文件或目录
[root@iZerb5rob3dcf6Z ~]# ll stdout.txt
-rw-r--r-- 1 root root 0 6月 11 19:07 stdout.txt
由于我们只重定向了标准输出而不是标准错误,该错误消息仍被发送到屏幕。而此时stdio.txt文件夹为空,这是因为,当我们使用“>”重定向输出时,始终从头开始重写目标文件。而ls命令没有产生任何结果,只有一条错误消息,重定向操作开始重写文件,然后由于错误而停止,导致其被截断。如果我们不想文件内容被覆盖则可以使用“>>”,此操作为追加:
[root@iZerb5rob3dcf6Z ~]# ll stdout.txt
-rw-r--r-- 1 root root 97414 6月 11 19:15 stdout.txt
[root@iZerb5rob3dcf6Z ~]# ll /usr/bin/ >> stdout.txt
[root@iZerb5rob3dcf6Z ~]# ll stdout.txt
-rw-r--r-- 1 root root 194828 6月 11 19:15 stdout.txt
可以看大文件内容有所增长。
输出重定向:‘>’: 覆盖输出
‘>>’:追加输出
重定向标准错误
fd:file descriptor ,文件描述符
标准输入:0
标准输出:1
标准错误:2
Shell提供了使用文件描述符重定向的方法。由于标准错误与文件描述符编号2相匹配,所以我们可以使用以下符号重定向标准错误:
[root@iZerb5rob3dcf6Z ~]# ls -l /bin/usr 2> stderr.txt
[root@iZerb5rob3dcf6Z ~]# cat stderr.txt
ls: 无法访问/bin/usr: 没有那个文件或目录
[root@iZerb5rob3dcf6Z ~]#
将标准输出和标准错误输入到同一个文件
有两种方法可供选择:
- 将标准输出重定向到文件
output.txt,然后将文件描述符2(标准错误)重定向到标准输出1(标准输出),使用符号2>&1。
[root@iZerb5rob3dcf6Z ~]# ls -l /bin/usr > output.txt 2>&1
[root@iZerb5rob3dcf6Z ~]# cat output.txt
ls: 无法访问/bin/usr: 没有那个文件或目录
请注意,重定向的顺序很重要。
- 使用单符号
&>重定向标准输出和标准错误到文件output.txt。也可以追加标准输出和标准错误流到单个文件,如下所示:
[root@iZerb5rob3dcf6Z ~]# ls -l /bin/usr &> output.txt
[root@iZerb5rob3dcf6Z ~]# cat output.txt
ls: 无法访问/bin/usr: 没有那个文件或目录
[root@iZerb5rob3dcf6Z ~]# ls -l /bin/usr &>> output.txt
[root@iZerb5rob3dcf6Z ~]# cat output.txt
ls: 无法访问/bin/usr: 没有那个文件或目录
ls: 无法访问/bin/usr: 没有那个文件或目录
[root@iZerb5rob3dcf6Z ~]#
处理不需要的输出
有时我们不想要程序的输出,只想要其执行返回状态。系统提供了一种通过将输出重定向到名为“/dev/null”的特殊文件来实现此目的的方法。该文件是一个称为比特桶的系统设备,它接受输入并且不执行任何操作。我们这样做:
[root@iZerb5rob3dcf6Z ~]# ls -l /bin/usr &> /dev/null
重定向标准输入
以下我们将简单介绍使用标准输入的命令。
cat–串联文件
cat命令读取一个或多个文件,并将它们复制到标准输出,如下所示:
cat file ...
显示文件内容。cat常用来显示短片:
[root@iZerb5rob3dcf6Z ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
......
由于cat可以接受多个文件作为参数,因此它也可以用于将文件连接在一起。假设我们下载了一个大文件,该文件已拆分为多个文件部分,我们希望将它们重新组合。使用方法:
[root@iZerb5rob3dcf6Z ~]# echo 1 > movie1
[root@iZerb5rob3dcf6Z ~]# echo 2 > movie2
[root@iZerb5rob3dcf6Z ~]# echo 3 > movie3
[root@iZerb5rob3dcf6Z ~]# echo 4 > movie4
[root@iZerb5rob3dcf6Z ~]# cat movie{1,2,3,4}
1
2
3
4
如果输入不带参数的“cat”,它将从标准输入读取,因为标准输入默认情况下已连接到键盘,它正在等待我们输入内容!输入Ctrl-C告诉cat在标准输入上到达文件末尾(EOF):
[root@iZerb5rob3dcf6Z ~]# cat
welcom to kingstar !
welcom to kingstar !
^C
[root@iZerb5rob3dcf6Z ~]#
#我们可以使用此行为来创建短文本文件并且输出内容
[root@iZerb5rob3dcf6Z ~]# cat > cat.txt
welcom to kingstar !my name is Mr.YANG .
^C
[root@iZerb5rob3dcf6Z ~]# cat < cat.txt
welcom to kingstar !my name is Mr.YANG .
[root@iZerb5rob3dcf6Z ~]#
| 管道(pipe)
连接程序,实现将前一个命令的标准输出做为后一个命令的标准输入。
[root@iZerb5rob3dcf6Z ~]# ls -l /usr/bin/ | less
总用量 148516
-rwxr-xr-x. 1 root root 41488 8月 20 2019 [
-rwsr-xr-x 1 root root 53048 10月 31 2018 at
lrwxrwxrwx 1 root root 2 4月 26 15:55 atq -> at
lrwxrwxrwx 1 root root 2 4月 26 15:55 atrm -> at
......
:q
| 与 > 的区别
重定向操将命令与文件连接起来,而管道操作将一个命令的输出传递给第二个命令的输入。
command1 > file1
command1 | command2
有的人可能会这样尝试:
[root@iZerb5rob3dcf6Z ~]# cat > cat
safegra
^C
[root@iZerb5rob3dcf6Z ~]# cat cat
safegra
而以下某些操作则可能会带来灾难:
[root@iZerb5rob3dcf6Z ~]# cd /usr/bin
[root@iZerb5rob3dcf6Z bin]# ls | less
这将会导致less命令被覆盖。重定向操作会静默创建或覆盖文件,因此您需要非常谨慎。
uniq - 报告或省略重复的行
uniq命令通常与sort结合使用。uniq接受排序列表作为标准输入或单个文件名参数的数据,并且默认情况下会从列表中删除所有重复项。
[root@iZerb5rob3dcf6Z ~]# cat num.txt | sort | uniq
1
123
2
3
42
44
#如果要查看重复项列表
[root@iZerb5rob3dcf6Z ~]# cat num.txt | sort | uniq -c
2 1
1 123
2 2
2 3
1 42
1 44
wc – 打印行数,字数和字节数
wc(word count)命令用于显示行数,字数和字节数包含在文件中。例如:
[root@iZerb5rob3dcf6Z ~]# wc /etc/passwd
21 30 920 /etc/passwd
在这种情况下,它将打印出三个数字:文件中包含的行,字和字节。就像我们之前的命令一样,如果不使用命令行参数执行,wc接受标准输入。“-l”选项显示行数。添加它连接到管道是一种方便的方法。我们可以这样做:
[root@iZerb5rob3dcf6Z ~]# cat num.txt | sort | uniq | wc -l
6
grep –打印匹配模式的行
grep是一个功能强大的程序,用于在文件中查找文本模式。它的用法如下:
grep pattern [file...]
当grep在文件中遇到“模式”时,它会打印出包含该模式的行。
[root@iZerb5rob3dcf6Z ~]# ls /bin /usr/bin | sort | uniq | grep zip
gpg-zip
gunzip
gzip
zip
zipcloak
zipnote
zipsplit
grep有几个方便的选项:“-i”使grep忽略大小写执行搜索时(通常搜索区分大小写),“-v”表示grep仅打印与模式不匹配的行。
head / tail
[root@iZerb5rob3dcf6Z ~]# head -n 5 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@iZerb5rob3dcf6Z ~]# tail -n 5 /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
#也可以在管道里使用
[root@iZerb5rob3dcf6Z ~]# ls /usr/bin/ | tail -n 3
zmore
znew
zsoelim
tail有一个选项,可让您实时查看文件。这对于观看记录日志文件时的进度。
[root@iZerb5rob3dcf6Z ~]# tail -f -n 6 /var/log/messages
Jun 11 21:01:01 iZerb5rob3dcf6Z systemd: Started Session 359 of user root.
Jun 11 21:10:01 iZerb5rob3dcf6Z systemd: Started Session 360 of user root.
Jun 11 21:20:01 iZerb5rob3dcf6Z systemd: Started Session 361 of user root.
Jun 11 21:29:16 iZerb5rob3dcf6Z auditd[611]: Audit daemon rotating log files
Jun 11 21:30:01 iZerb5rob3dcf6Z systemd: Started Session 362 of user root.
Jun 11 21:40:01 iZerb5rob3dcf6Z systemd: Started Session 363 of user root.
Jun 11 21:45:48 iZerb5rob3dcf6Z systemd-logind: Removed session 333.
Jun 11 21:46:01 iZerb5rob3dcf6Z systemd: Started Session 364 of user root.
Jun 11 21:46:01 iZerb5rob3dcf6Z systemd-logind: New session 364 of user root.
tee
tee程序读取标准输入并将其复制到标准输出(允许数据继续沿管道传输)和一个或多个输出文件。
[root@iZerb5rob3dcf6Z ~]# ls /root/My_Hexo/ | tee root_My
_config.yml
db.json
node_modules
package.json
package-lock.json
scaffolds
source
themes
yarn.lock
[root@iZerb5rob3dcf6Z ~]# cat root_My
_config.yml
db.json
node_modules
package.json
package-lock.json
scaffolds
source
themes
yarn.lock