linux系统每个对像当做文件来处理。这包括输入和输出的过程。linux用文件描述来标识每个文件对象。文件描述符是一个非负整数,可以唯一地标识会话中打开的文件。每个过程一次最多可以有9个文件描述符。出于特殊目的。bash shell保留了最早的3个文件描述符{0,1,2}分别对应{STDIN,STDOUT,STDERR}表示为标准输入、标准输出、标准错误。我们先来一段代码看看

  1 #!/bin/bash
  2 exec 3>&1            

  3 exece 1>inputfile                                       

  4 exec 2>errorfile                                        
  5 echo "this is a mao shu fu"                      
  6 echo "look at this example"                    
  7 echo "this is error1" >&2                         
  8 echo "this is error2" >&2                         
  9 exec 1>&3                                                   

 10 exec 5<&0
 11 exec 0<errorfile
 12 while read line
 13 do
 14 echo "this is errorfile content $line"    
 15 done
 16 exec 0<&5

 17 read -p "you can continue" var
 18 echo "the script end"  

  这其中我们设置了{0,1,2,3,5}共5个文件描述符,为避免重复使用同一描述符,应在使用描述前,查看当前使用了哪些描述符。要想查看当前shell使用了哪些描述符可以全用lsof -a -p $$ -d 0,1,2  -a 相当于and,依次对后面参数做and操作 -p表示显示进程的pid 要知道进程当前的pid,用$$,shell会将它设置为当前pid。

  假如我在第9行中插入sleep 10让脚本休眠10秒,在执行的时候把这个脚本设置为后台运行,就可以使用lsof -a -p $$ -d 3,就可以显示描述符3正在被使用,同时会显示脚本的pid号。

 现在我们来讲一下,脚本各项的意思,

   1 主要创建了描述符3,它批向1(标准输出)也就说是显示器。

   2 输出指向文件

   3 错误输出指定到文件,

   [5-6] 主要在显示器上显示两条语句,但是标准输入已经被我们指定到文件了,所有这两句没有显示,在我们指定的文件inputfile中

   [7-8] 我们把这两条做为错误输出,因为之前的我把错误输出指定到了errorfile文件中,在这两条语句末加上&2,就把他们指定到错误输出所指定的文件中。

   9 因为第二条语句exece 1>inputfile已经把1指向了inputfile,所以我用第9条语句把标准输出指向到描述符3,而描述符则向显示器(exec 3>&1),那为描述符1自然就重新指向显示器了。如果删除了第9条语句。插入一条echo "can view" 它是不会显示在显示器上面的,因为描述符1还指向着inputfile。加第九条语句,让描述符1重新指向显示器,可以显示can view

   按照上面的解释我们就可以轻松的明白[10-18]行所表示的意了,[10-18]是标准输入。参照上面的解释即可。