Linux呈现数据

目录

一、理解输入和输出

1.1 标准文件描述符

 1.1.1 STDIN

 1.1.2 STDOUT

 1.1.3 STDERR

1.2 重定向错误

二、在脚本中重定向输出

2.1 临时重定向

2.2 永久重定向 

三、在脚本中重定向输入

四、创建自己的重定向

4.1 创建输出文件描述符 

 4.2 重定向文件描述符

4.3 关闭文件描述符 


一、理解输入和输出

1.1 标准文件描述符

Linux系统会将每个对象作为文件来处理,这包括输入和输出。Linxu用文件描述符来标识每个文件对象。文件描述符是一个非负整数,每个进程一次最多可以打开9个文件描述符。出于特殊目的,bash shell保留了前3个文件描述符(0、1和2)

Linux标准文件描述符
文件描述符缩写描述
0STDIN标准输入
1STDOUT标准输出
2STDERR标准错误

 1.1.1 STDIN

STDIN文件描述符代表shell的标准输入。对终端界面来说,标准输入是键盘。在使用输入重定向符(<)时,Linux会用重定向指定的文件替换标准输入文件描述符(即0),命令就会从文件中读取数据,就像从键盘中输入的一样

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat < testfile
hello world
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

 1.1.2 STDOUT

STDOUT文件描述符代表shell的标准输出。在终端界面上,标准输出就是终端显示器。在默认情况下,大多数bash命令会将输出送往STDOUT文件描述符。可以用输出重定向来更改此设置。

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ls > test_stdout.txt
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test_stdout.txt
script
testfile
test_stdout.txt
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

1.1.3 STDERR

在默认情况下,STDOUT和STDERR指向同一个地方(尽管二者的文件描述符索引值不同) ,也就是说都会显示在屏幕上。STDERR并不会随着STDOUT的重定向发生改变,STDERR文件描述符是2。

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ls bb.txt
ls: cannot access bb.txt: No such file or directory
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ls bb.txt 2> test_stderr.txt
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test_stderr.txt
ls: cannot access bb.txt: No such file or directory
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

1.2 重定向错误

如果想重定向错误信息和正常输出,则必须指定两个重定向符号

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ls script bbfile
ls: cannot access bbfile: No such file or directory
script:
aa.exp
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ls script bbfile 2> test1 1> test2
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat  test1
ls: cannot access bbfile: No such file or directory
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test2
script:
aa.exp
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

 上例中,ls命令的正常输出本该送往STDOUT,shell使用 1> 将其重定向到了文件test2,而本该送往STDERR的错误信息则通过 2> 被重定向到了文件test1中。

另外你还可以将STDOUT和STDERR的输出重定向到同一个文件,重定向符 &>

二、在脚本中重定向输出

2.1 临时重定向

如果你有意在脚本中生成错误信息,可以将单独的一行重定向到STDERR。这只需要使用输出重定向符号将输出重定向到STDERR 文件描述符。在重定向到文件描述符时,必须在文件描述索引值之前加一个&

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test8
#! /bin/bash

echo "This is an error" >&2
echo "This is normal output"
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ./test8
This is an error
This is normal output
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

如果单独运行脚本看不出任何区别,因为,默认情况下,STDOUT和STDERR指向的位置是一样的。但是如果在运行脚本时重定向了STDERR,那么脚本中所有送往STDERR的文本就会被重定向 

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ./test8 2> test9
This is normal output
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test9
This is an error
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

2.2 永久重定向 

如果脚本中有大量数据需要重定向,那么逐条重定向就会很麻烦,这时可以用 exec 命令,它会告诉shell在脚本执行期间重定向某个特定文件描述符:

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test10
#! /bin/bash

exec 1>testout

echo "nihao"
echo "zhongguo"
echo "hahah"
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ./test10
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat testout
nihao
zhongguo
hahah
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

 exec会启动一个新的shell并将STDOUT文件描述符重定向到指定文件。脚本中送往STDOUT的所有输出都会被重定向。

也可以在脚本执行过程中重定向STDERR

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test11
#! /bin/bash

exec 2>testerr

echo "这是标准输出1"
echo "这是标准输出2"
echo "这是标准输出3"

exec 1>testout

echo "这里的输出将会重定向到指定文件"
echo "这行将会重定向到标准错误" >&2
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ./test11
这是标准输出1
这是标准输出2
这是标准输出3
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat testout
这里的输出将会重定向到指定文件
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat testerr
这行将会重定向到标准错误
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

该脚本使用 exec 命令 将送往STDERR的输出重定向到了文件testerr。接下来,脚本用echo语句向STDOUT显示了几行文本。随后再次使用 exec 将STDOUT重定向到文件testout。注意,尽管STDOUT被重定向了。然然可以将echo语句的输出发送给STDERR,本例中仍是被重定向到了testerr文件。

一旦重定向了STDOUT或STDERR,就不太容易将其恢复到原来的位置,如果需要再重定向中来回切换,那么就要用到后面介绍的创建自己的重定向

三、在脚本中重定向输入

相同的方法,可以使用重定向将STDIN从键盘重定向到其他位置。在Linux系统中允许将STDIN重定向为文件:

exec 0< testfile

 该命令会告诉shell,他应该从文件testfile中而不是键盘上获取输入。

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat testfile
this is the first line
this is the second line
this is the third line
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test12
#! /bin/bash

exec 0< testfile

count=1

while read line
do
  echo "Line #$count: $line"
  count=$[ $count + 1 ]
done
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ./test12
Line #1: this is the first line
Line #2: this is the second line
Line #3: this is the third line
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

 将STDIN重定向为文件后,当read命令试图冲STDIN读入数据时,就会到文件而不是键盘上检索数据。

这是一种在脚本中从待处理的文件中读取数据的绝妙技术。Linux管理员的日常任务之一就是从日志文件中读取并处理数据,这是完成该任务的最简单的办法。

四、创建自己的重定向

在脚本中重定向输入和输出时,并不局限于这3个默认的文件描述符。在shell中最多可以打开9个文件描述符。替代性文件描述符从3到8共6个,均可以用作输入或输出重定向。 

4.1 创建输出文件描述符 

可以用 exec  命令用于分配输出的文件描述符。和标准文件描述符一样,一旦将替代性文件描述符指向文件,此定向就会一直有效,直至重新分配。

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test13
#! /bin/bash

exec 3> test13out

echo "输出到显示器"
echo "输出到指定文件" >&3
echo "也是输出到屏幕"
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ./test13
输出到显示器
也是输出到屏幕
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test13out
输出到指定文件
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

 4.2 重定向文件描述符

有一个技巧能帮助你恢复到已重定向的文件描述符。你可以将另一个文件描述符分配给标准文件描述符,反之亦可。这意味着可以将STDOUT的原先位置重定向到另一个文件描述符,然后再利用该文件描述符恢复STDOUT。

[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test14
#! /bin/bash

exec 3>&1
exec 1> test14out

echo "改行内容将会重定向到test14out中"

exec 1>&3

echo "这行内容将正常显示在屏幕上"
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# ./test14
这行内容将正常显示在屏幕上
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]# cat test14out
改行内容将会重定向到test14out中
[root@iZbp1ir1vzqwzkdy7mvjthZ ~]#

 该脚本中,第一个 exec 命令将文件描述符3重定向到文件描述符1(STDOUT)的当前位置,也就是显示器。

第二个 exec 命令将STDOUT重定向到了文件。但是,文件描述符 3 扔指向显示器。如果此时将输出数据发送给文件描述符 3 ,他仍然会显示在屏幕上,即使STDOUT已经被重定向了。

向STDOUT(现在指向一个文件)发送一些输出之后,第三个 exec 命令将STDOUT重定向了文件描述符 3 的当前位置(现在仍然是显示器)。这意味着现在STDOUT又恢复如初了。

4.3 关闭文件描述符 

如果创建了新的输入文件描述符或输出文件描述符,那么shell会在脚本退出时自动将其关闭。然而在一些情况下,需要在脚本结束前手动关闭文件描述符。

要关闭文件描述符,只需将其重定向到特殊符号 &- 即可

exec 3>&-

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值