美文网首页Shell 脚本成长笔记
Shell 重定向(四):文件描述符

Shell 重定向(四):文件描述符

作者: 赵者也 | 来源:发表于2017-05-19 21:42 被阅读52次

    Shell 有时会引用使用文件描述符(fd)的文件。我们一般使用文件描述符(fd)的范围是数字 0~9。重定向时大于 9 的文件描述符要谨慎使用,因为它们可能与 Shell 内部使用的文件描述符冲突。

    文件描述符可以包含多个数字位。例如,文件描述符 001 和 01 与文件描述符 1 是相同的。多种操作(例如,exec 命令)都可以将文件描述符与特定的文件联系起来。

    有些文件描述符是在 Shell 启动时被建立的,这就是我们前面介绍的标准输入、标准输出和标注错误(0、1、2)文件描述符。

    实例:使用 exec 命令

    Bash 的内部命令 exec 的功能之一就是允许我们操作文件描述符。如果在 exec 之后没有指定命令,则 exec 命令之后的重定向将更改当前 Shell 的文件描述符。

    例如,在命令 “exec 2> file” 之后运行的所有命令,都会将其产生的错误信息发送到文件 file 中,就像你的命令在脚本 myscript.sh 中,而你运行的是 “./myscript.sh >2 file”。

    比如,如果你想记录脚本中的命令产生的错误信息,就可以在脚本的开头使用类似如下的命令:

    exec 2> errors.log
    

    下面我们来看一个脚本文件,在这个脚本中我们想要顺序地读取文件中的每一行,并在打印每一行之后,等待用户输入任意键后继续。

    #! /bin/bash
    
    if [ $# -lt 1 ]; then
        echo "Usage: $0 FILEPATH"
        exit
    fi
    
    file=$1
    
    while read -r line
    do
        echo $line
        read -p "Press any key" -n 1
    done < $file
    
    运行结果

    从上面的输出结果我们可以看到,read 语句并没有执行:因为我们将指定的文件重定向到了 while 循环的标准输入(文件描述符 0),即我们指定的文件将被打开以用于标准输入的读取,而循环中的所有命令包括 read 命令都会继承这个文件描述符(这里是标准输入),因此 read 将从重定向后的标准输入读取,而不是从默认的标准输入设备(键盘)读取。

    而此时,我们就可以使用 exec 命令对脚本稍加改动,来实现我们想要的功能,改动后的脚本将类似如下所示:

    #! /bin/bash
    
    if [ $# -lt 1 ]; then
        echo "Usage: $0 FILEPATH"
        exit
    fi
    
    # 将脚本的第一个参数作为输入文件,并制定一个文件描述符 3
    exec 3< $1
    
    while read -u 3 line
    do
        echo $line
        read -p "Press any key: " -n 1
    done
    
    # 关闭文件描述符 3
    exec 3<&-
    

    在上述脚本中,我们使用的 “read -u 3 line” 命令,为 read 指定从指定的描述符中读取数据。

    上述脚本的运行效果

    运行结果

    本文参考自 《Linux Shell命令行及脚本编程实例详解

    相关文章

      网友评论

        本文标题:Shell 重定向(四):文件描述符

        本文链接:https://www.haomeiwen.com/subject/kwlexxtx.html