为什么在Bash的'read'循环结束时重定向?

时间:2013-08-22 21:08:47

标签: bash while-loop init io-redirection

我在CentOS的init.d脚本中看到一个有趣的'read'循环,可以归结为基本上这个结构:

cat "somefile" | while read var1 var2; do
    # do something with vars 1 and 2
done 3<&1

我实验性地取消了“3&lt;&amp; 1”重定向,并且在执行或行为方面没有任何改变......最终的重定向“3&lt;&amp; 1”实现了什么,为什么它在最后专门完成循环?

下面你会找到完整的init脚本,它适用于处理加密文件系统密钥管理的Gazzang的zNcrypt服务。我感兴趣的部分发生在“开始”和“停止”案例的结尾。

#! /bin/sh
#
# zncrypt       This script mount and umount all zncrypt directories
#
# chkconfig: - 64 36
# description:  zNcrypt start script.

. /etc/rc.d/init.d/functions

if [ -r /usr/lib/zncrypt/zncrypt.functions ]; then
        . /usr/lib/zncrypt/zncrypt.functions
else
        echo "/usr/lib/zncrypt/zncrypt.functions: File does not exist."
        exit 0
fi

ZNCRYPT_LOG_DIR="/var/log/zncrypt"
ZNCRYPT_LOG_ACCESS_FILE=$ZNCRYPT_LOG_DIR"/access.log"

# create zncrypt log directory
mkdir -p "$ZNCRYPT_LOG_DIR"

# create access log file for the kernel module
touch "$ZNCRYPT_LOG_ACCESS_FILE"

case "$1" in
start)
        echo "Starting zNcrypt directories"
        egrep -v "^[[:space:]]*(#|$)" "$ZTABFILE" | while read mnt src type opts; do
                if ! df "$mnt" | grep "$mnt$" >/dev/null; then
                        action $" * Mounting $src ... " do_mount "$src" "$mnt" "$type" "$opts" < /dev/tty
                fi
        done 3<&1
;;
stop)
        echo "Stopping zNcrypt directories"
        egrep -v "^[[:space:]]*(#|$)" "$ZTABFILE" | while read mnt src type opts; do
                if df "$mnt" | grep "$mnt$" >/dev/null; then
                        action $" * Umounting $src ... " do_umount "$mnt"
                fi
        done 3<&1

        if /sbin/lsmod | grep ^zncryptfs &>/dev/null; then
                action $" * Unloading module ... " /sbin/rmmod zncryptfs 2>/dev/null && rm /dev/zncrypt 2>/dev/null
        fi
;;
status)
        show_status
;;
restart)
        /bin/bash $0 stop
        sleep 1
        /bin/bash $0 start
;;
reload|force-reload)
;;
force-start)
;;
*)
        echo "Usage: `basename $0` {start|stop|status|restart}"
        exit 1
        ;;
esac

1 个答案:

答案 0 :(得分:1)

3<&1告诉bash shell将来自stdout(文件描述符1)的任何内容重定向到文件描述符3。文件描述符3将对应于在cat / while构造的上下文中打开的某个文件或设备。有关标准文件描述符,请参阅this article。另请参阅此related post