I/O重定向、管道

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

  1. 若使用命令“echo”只能逐行输出。
  2. 该命令谐音为字母“T”,正好是从一个位置输入,再输出至两个位置(指定文件和显示器)。
  3. 当然,命令“wc -l”是支持多个参数的,这里主要是为了查看命令xargs的功能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值