0.目录
1.三种数据流
三种数据流是指:输入流、输出流、错误输出流,可以使用多种设备实现。
标准的输入输出:
标准 | 设备 | 文件描述符(fd) |
---|---|---|
标准输入 | 键盘 | 0 |
标准输出 | 显示器 | 1 |
标准错误输出 | 显示器 | 2 |
2.输入重定向与“<<”一次输出多行文本
2.1 输入重定向“<”
输入重定向是指:把标准输入(键盘)改为其他输入。
输入重定向使用“<”实现。
以命令“cat”为例:
使用命令“cat”不带参数,系统会等待用户从键盘输入,并显示输入的内容:[root@localhost ~]# cat Hello,how old are you? # 键盘输入 Hello,how old are you? # 回车后显示
使用输入重定向,用某文件的内容,代替键盘成为命令“cat”的输入:
[root@localhost ~]# cat < ~/hello.test Hello,how old are you? # 文件hello.test中的内容
不过命令“cat”可把文件作为参数,无需专门输入重定向。
以命令“tr”为例:
命令“tr”是只能从标准输入读取数据的命令。
使用命令“tr”,把从标准输入的小写字母,都转换为大写字母:[root@localhost ~]# tr "a-z" "A-Z" # 把输入内容中的小写字母转换为大写 hello,how old are you? # 键盘输入的内容 HELLO,HOW OLD ARE YOU? # 输出结果
使用输入重定向,用某文件的内容,代替键盘成为命令“tr”的输入:
[root@localhost ~]# tr 'a-z' 'A-Z' < ~/hello.test HELLO,HOW OLD ARE YOU? # 把hello.test中的字母均转换为了大写
2.2 “<<”一次性输出多行文本
符号“<<”,配合命令“cat”,可将所有输入的数据一次性输出,可用于脚本中多行文本的输出1。
[root@localhost ~]# cat << EOF # EOF表示结束符,回车后可从键盘输入数据
> Hello,how old are you?
> What’s your name?
> My name is Tom.
> EOF # 从键盘输入完毕后,再以EOF结尾
Hello,how old are you? # 输出结果
What’s your name?
My name is Tom.
以上为固定的格式,不过两个“EOF”也可以是其他字符,只要前后保持一致即可。
实现键盘输入数据直接存至文件:
[root@localhost ~]# cat > hello.test << EOF
> Please sit down.
> EOF
[root@localhost ~]# cat hello.test
Please sit down.
[root@localhost ~]# cat >> hello.test << EOF
> Please stand up
> EOF
[root@localhost ~]# cat hello.test
Please sit down.
Please stand up
以上两段内容,用法一样,只是把要输出至屏幕的内容覆盖重定向、追加重定向至文件“hello.test”了。
3.输出重定向
输出重定向是指:把标准输出(显示器)改为其他输出。
覆盖输出重定向
覆盖输出重定向使用“>”实现。把输出至显示器的内容,改为输出至文件(若文件不存在则自动创建):
[root@localhost ~]# echo "My name is Tom." > hello.test [root@localhost ~]# cat hello.test My name is Tom.
也可重定向至其他终端,使内容在其他终端上显示,指定对应的设备文件即可:
[root@localhost ~]# cat hello.test > /dev/tty1
覆盖重定向至某文件后,会覆盖原数据,所以不应随便使用其指向文件(尤其设备文件)。
由此,可以使用“set -C”,使覆盖输出重定向不能定向至已存在的文件(仅对当前shell有效)。在此种情况下,如果确定内容确实需要覆盖,也可使用“>|”实现覆盖输出重定向。还原可使用“set +C”。
[root@localhost ~]# set -C; echo hi > hello.test -bash: hello.test: cannot overwrite existing file [root@localhost ~]# set +C; echo hi > hello.test [root@localhost ~]# cat hello.test hi # 设置能否使用覆盖重定向至已存在的文件
[root@localhost ~]# set -C; echo hello > hello.test -bash: hello.test: cannot overwrite existing file [root@localhost ~]# echo hello >| hello.test [root@localhost ~]# cat hello.test hello # 在“set -C”的情况下,仍需使用覆盖重定向
追加输出重定向
追加输出重定向,使用“>>”实现。
用法同覆盖重定向,只是不再覆盖原有数据,而会把内容追加至原内容尾部。若追加重定向的文件不存在,同样会自动创建。[root@localhost ~]# cat hello.test hello [root@localhost ~]# echo thanks >> hello.test [root@localhost ~]# cat hello.test hello thanks
4.错误输出重定向
错误输出重定向是指:把标准输出(显示器)改为其他输出
错误输出重定向也有覆盖和追加,效果同标准输出重定向,只不过重定向的是错误输出流。
覆盖错误输出重定向
覆盖错误输出重定向可使用“2>”实现。把默认输出至显示器的错误输出流,输出至文件(若文件不存在则自动创建):
[root@localhost ~]# lss / 2> lss.txt [root@localhost ~]# cat lss.txt -bash: lss: command not found
注意,命令“set -C”也可使覆盖错误输出重定向不能定向至已存在的文件(仅对当前shell有效)。在此种情况下,如果确定内容确实需要覆盖,也可使用“2>|”实现错误覆盖输出重定向。还原可使用“set +C”。
追加错误输出重定向
类似地,追加错误输出重定向可使用“2>>”实现(若文件不存在则自动创建)。
接上例:[root@localhost ~]# cat /Not_Exist 2>> lss.txt [root@localhost ~]# cat lss.txt -bash: lss: command not found cat: /Not_Exist: No such file or directory
5.同时定向标准输出流、错误输出流
5.1 标准输出、错误输出同时定向至同一位置
覆盖的情况:
[root@localhost ~]# touch /tmp/test1 /tmp/test2 /tmp/test3
[root@localhost ~]# ls /tmp/ &> a # 实现标准输出重定向
[root@localhost ~]# cat a
test1
test2
test3
[root@localhost ~]# lss /tmp/ &> a # 实现错误输出重定向
[root@localhost ~]# cat a
-bash: lss: command not found
追加的情况:
[root@localhost ~]# ls /tmp/ &> a
[root@localhost ~]# cat a
test1
test2
test3
[root@localhost ~]# lss /tmp/ &>> a # 追加错误输出流
[root@localhost ~]# ls /tmp/ &>> a # 追加标准输出流
[root@localhost ~]# cat a
test1
test2
test3
-bash: lss: command not found
test1
test2
test3
使用如下操作,也可实现标准输出、错误输出定向至同一位置。固定格式,效果不再赘述。
[root@localhost ~]# lss /tmp/ > test 2>&1 # 覆盖
[root@localhost ~]# ls /tmp/ >> test 2>&1 # 追加
5.2 标准输出、错误输出同时定向至不同位置
使用覆盖重定向,正常输出定向至文件test1,错误输出定向至文件test2:
[root@localhost ~]# ls /tmp/ > test1 2> test2
[root@localhost ~]# cat test1; cat test2
test1
test2
test3
[root@localhost ~]# lsss /tmp/ > test1 2> test2
[root@localhost ~]# cat test1; cat test2
-bash: lsss: command not found
# 由于是覆盖重定向,test1、test2任何一个接收内容,另一个会变为空,因为二者的执行结果一定会有一个为空。
改为追加重定向:
[root@localhost ~]# ls /tmp/ >> test3 2>> test4
[root@localhost ~]# lsss /tmp/ >> test3 2>> test4
[root@localhost ~]# cat test3; cat test4
test1
test2
test3
-bash: lsss: command not found
[root@localhost ~]# ls /tmp/ >> test3 2>> test4
[root@localhost ~]# lsss /tmp/ >> test3 2>> test4
[root@localhost ~]# cat test3; cat test4
test1
test2
test3
test1
test2
test3
-bash: lsss: command not found
-bash: lsss: command not found
显然以上的方式也可把标准输出、错误输出定向至同一位置,“&>”、“&>>”可看做其简写。
标准输出、错误输出,可根据需要,分别使用覆盖或追加重定向,二者不是必须一致。
5.3 /dev/null
/dev/null,数据黑洞,也称位桶,定向输出至此设备表示直接丢弃。
[root@localhost ~]# ls / > /dev/null
[root@localhost ~]# # 不输出任何结果
[root@localhost ~]# echo $? # 此时可通过“$?”的值查看命令执行是否成功
0
6.匿名管道
6.1 匿名管道
匿名管道,表示把前一个命令的输出,当做后一个命令的输入,使用“|”实现。
[root@localhost ~]# echo "hello,how are you." | tr a-z A-Z
HELLO,HOW ARE YOU.
如上,命令“echo”的结果不输出至显示器,而是作为命令“tr”的输入。
也可连接多条命令:
[root@localhost ~]# cat /etc/init.d/functions | grep -o "if" | wc -l
111
6.2 命令tee
命令tee,表示从标准输入读取内容,并输出至标准输出和指定文件,若无指定文件则仅输出至标准输出2。
[root@localhost ~]# echo "abc" | tee test1 | tr 'a-z' 'A-Z'
ABC
[root@localhost ~]# cat test1
abc
如上,输出至显示器的“abc”,由管道送给命令“tee”,则保存在文件“test1”中,且本应也输出至显示器,但又通过管道作为命令“tr”的参数进行了处理。
6.3 命令xargs
命令xargs,在管道中使用,可使前面命令的结果,被后面的命令依次逐个处理,而非把前面命令的结果一次性传递给后面的命令。
比如,查看多个文件的行数3。
[root@localhost tmp]# ls
test1 test2
[root@localhost tmp]# ls | wc -l # 前面命令的结果一次性传递给后面,后面命令把它当做一整个文本来处理,所以结果是2。
2
[root@localhost tmp]# ls | xargs wc -l # 有了命令xargs,后面的命令会把前面命令的结果,逐个作为参数运行(且不把它们看做文本,否则结果就都是1了)。
1 test1
15 test2
16 total
这个如果是1个文件的情况或许更明显:
[root@localhost tmp]# wc -l test2
15 test2
[root@localhost tmp]# ls test2 | wc -l # 把前面命令的结果当做一整个文本处理
1
[root@localhost tmp]# ls test2 | xargs wc -l # 把前面命令的结果当做参数处理
15 test2