[置顶] linux exec和文件描述符妙用技巧

      最近在看《精通unix shell脚本编程》时,看到exec<$1 exec 1>$OUTFILE,一下看的我就蒙了。网上看了大半天,终于搞定,记录如下。

      对于 Linux 而言,所有对设备和文件的操作都使用文件描述符来进行的。
      文件描述符是一个非负的整数,它是一个索引值,并指向内核中每个进程打开文件的记录表。
      当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数。

      通常,一个进程启动时,都会打开 3 个文件:标准输入、标准输出和标准出错处理。这3 个文件分别对应文件描述符为 0、1和2也就是宏替换 STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO。

      查看和设置LINUX文件描述符数
       ulimit -n
       ulimit -n1024

 

 实例一:通过exec分配文件描述符


              exec 3<>hello.txt               # 以读写方式绑定到文件描述符"3"
              echo "hello exec" >&3       # 写入"hello exec",如果之前有内容,这里将会从文件开头进行覆盖
              echo "hello world" >&3      # 写入"hello world“,新的一行!
              exec 3>&-                          # 关闭写,禁止写,然而,实际上它也不能读了~
                                                         # 如果是exec 3<&-,关闭读,同时它也不能写了~


             在上面的示例中,将文件hello.txt绑定到了描述符3。

 实例二:将标准输出重定向

               exec 1>hello.txt        # 将输出重定向到文件hello.txt,从此以后,这个脚本中的输出都将被写入文件hello.txt
               echo "hello exec"
               echo "hello world"
 

 实例三:恢复重定向 


               exec 100>&1             # 将文件描述符100连接到标准输出
                                                 # 由于之后还要输出到终端,所以我们不得不使用一个临时的描述符来保存它!
               exec 1>hello.txt        # 将输出重定向到文件hello.txt,从此以后,这个脚本中的输出都将被写入文件hello.txt
               echo "hello exec"
               echo "hello world"
               exec 1>&100 100>&-      # 将标准输出连接到100,这是之前保存的标准输出
                                                       # 将描述符100关了,一了百了,因为已经还原标准输出了,留着它实在没必要

               echo "oh, my god!"      # 从这句开始将显示在终端上

 

 实例四:输入重定向 

               exec 100<&0
               exec <hello.txt
               read line1
               echo $line1
               read line2
               echo $line2

               exec 0<&100 100>&-

               read custom

 实例五:读写文件


               #!/bin/bash
               LANG=C
               echo "begin"
               OUTFILE="hello2.txt"
               INFILE="hello.txt"
               function file1
               {

                >$OUTFILE    #zero out the file ,相当于清空该文件
                exec 4>&1
                exec 1> $OUTFILE
                while read LINE
                do
                 echo "$LINE"
                 :
                done < $INFILE

                exec 1>&4
                exec 4>&-
               }
               file1
               echo "end"

 

 

 附 find 和exec妙用
               (1)在当前目录下(包含子目录),查找所有txt文件并找出含有字符串"bin"的行 
                             find ./ -name "*.txt" -exec grep "bin" {} \; 
  
               (2)在当前目录下(包含子目录),删除所有txt文件 
                             find ./ -name "*.txt" -exec rm {} \;

 

你可能感兴趣的:(linux,exec,文件描述符)