首页 > 代码库 > 数据呈现

数据呈现

重定向

1.文件描述符

linux用文件描述符标识每个文件对象,实现IO处理(输入输出)

每个过程一次最多可以用9个文件描述符,其中0-2有特殊含义。

文件描述符   缩写             描述                 备注  

0                  STDIN         标准输入          默认标准输入是键盘

1                  STDOUT    标准输出          默认标准输出是显示器

2                  STDERR    错误输出         默认错误输出是显示器

1.输入输出重定向(命令行)

1)输入重定向,使用<号:将要输入的内容更改为指定文件

标准输入命令:cat、wc等

# cat 
hello world   #键盘输入
hello world   #打印输入

输入重定向:

#wc < filename

2 4  16

2)输出重定向:

可以将命令的执行结果重定向输出到某个文件(默认标准输出到显示器)

>  file1      #将命令执行的标准输出到file1,覆盖

>> file1    #将命令执行的标准输出追加到file1,追加

2>  file1   #将命令执行的标准错误输出到file1,覆盖

2>> file1   #将命令执行的标准错误输出追加到file1,追加

&> file1    #将命令执行的标准输出和错误输出都重定向到file1(默认标准错误消息会显示在文件开头)

1> file1 2> file2  #将命令执行的标准输出到file1,标准错误输出到file2

#ls -l  &> file1   #将ls -l命令的执行结果(标准错误、标准输出)均输出到file1中,而不在显示器中显示。

1.输入输出重定向(脚本文件中)

临时重定向

>&2   #命令的输出结果,重定向输出到文件描述符2(标准错误默认输出到显示器)

>&1  #命令的输出结果,重定向输出到文件描述符1(标准输出默认输出到显示器)

#cat test1

#!/bin/bash

echo "This is an error message" >&2

echo "This is a normal message"

#./test1

This is an error message

This is a normal message

#./test 1 2> error.file   #将脚本中的标准错误,输出到error.file

This is a normal message

#cat error.file

This is an error message

永久重定向

exec 1> file  #将STDOUT文件描述符重定向到file文件,影响后续脚本的输出

exec 2> file   #将STDERR文件描述符重定向到file文件,影响后续脚本的输出

exec 0< file  #从file文件中获取输入,而不是键盘

举例1:标准输出重定向到文件

#cat file1
#!/bin/bash
exec 1> stdout.file   #后需的标准输出,均输出重定向到stdout.file中
echo "stdout line1"
echo "stdout line2"
#./file1
#cat stdout.file
stdout line1
stdout line2

举例2:多个exec

#cat file1
#!/bin/bash
exec 2> stderr.file   #后续标准错误,重定向到stderr.file文件
echo "stdout line1"
echo "stdout line2"
exec 1> stdout.file  #后续标准输出,重定向到steout.file文件
echo "stdout line3"
echo "stderr line1" >&2   #重定向到STDERR(标准错误)
#./file1
stdout line1
stdout line2
#cat stdout.file
stdout line1
stdout line2
#cat stderr.file
stderr line1

举例3:从stdin.file文件获取输入

#cat stdin.file
stdin line1
stdin line2
#cat file1.sh
#!/bin/bash
exec 0< stdin.file
count=1
while read line    #从stdin.file读取数据,而不是键盘
do
   echo "Line#$count: $line"
   count= $[ $count + 1 ]
done
#./file1.sh
Line#1: stdin line1
Line#2: stdin line2

自定义重定向

文件描述符3-8,当作输入或输出重定向都行

exec 3> file  #创建文件描述符3,将后续重定向到文件描述符3的内容,输出到file

exec 3>&1    #创建文件描述符3,将后续重定向到文件描述符3的内容,重定向到文件描述符1

exec 3<&0   #创建文件描述符3,将标准输入到文件描述符0的内容,输入重定向到文件描述符3

exec 3< file  #创建文件描述符3,将file的内容,输入重定向到文件描述符3

exec 3<> file  #同时读取、写入file

举例1:自定义的文件描述符重定向到文件

#test.sh
#!/bin/bash exec 3> stdout.file echo "stdout line1" echo "stdout line2" >&3
echo "stdout line3"
#./test.sh
stdout line1
stdout line3
#cat stdout.file
stdout line2

举例2:自定义的文件描述符重定向到另一文件描述符

#test.sh
exec 3>&1
exec 1> stdout.file 
echo "stdout line1"
echo "stdout line2"
exec 1>&3  #重新定义文件描述符1到3,上面定义了3到1,所以后续会标准输出
echo "stdout line3"
#./test.sh
stdout line3
#cat stdout.file
stdout line1
stdout line2

举例3:自动以文件描述符(费解)

# cat testfile 
line1
line2
[root@localhost test]# cat test1
#!/bin/bash
exec 6<&0        #STDIN输入到文件描述符6中
exec 0< testfile  #将testfile输入到STDIN中
count=1
while read line
do 
  echo "Line $$count: $line"
  count=$[ $count +1 ]
done
exec 0<&6  #将文件符6输出到STDIN
[root@localhost test]# ./test1
Line 1: line1
Line 2: line2
创建读写文件描述符

用同一个文件描述符,从文件读取、写入数据,shell会维护一个指针,用来在文件的位置。

# cat testfile 
this is the first line.
this is the second line.
this is the third line.
# cat test1
#!/bin/bash
exec 3<> testfile  
read line <&3      #从testfile读入1行数据,指针在第2行开始位置
echo "Read: $line"  
echo "this is a test line" >&3 #往testfile输入1行数据,覆盖指针位置的任何数据。
[root@localhost test]# ./test1
Read: this is the first line.
[root@localhost test]# cat testfile 
this is the first line.
this is a test line   #覆盖了this is the second l ,留了一个尾巴ine.未覆盖。
ine. 
this is the third line.

总结:

文件描述符与&或>之间不能加空格

>&  #加了&表示重定向到文件描述符

>   #不加&表示重定向到文件

exec 文件描述符1>&文件描述符2   #打开文件描述符1,重定向到文件描述符2

exec 文件描述符1> file1  #打开文件描述符1,重定向到file1

exec 文件描述符>&-    #文件描述符重定向到横线,表示关闭文件描述符

#cat test.sh
exec 1> stdout.file
echo "stdout line1"
exec 1>&-   #由于关闭了1,所以后续给1的内容,无法标准输出到显示器,所以第4行报错
echo "stdout line2"
#./test.sh
./test.sh: line 4: echo: write error: Bad file descriptor
#cat stdout.file
stdout line1

数据呈现