I saw an interesting 'read' loop in an init.d script for CentOS that can be boiled down to essentially this structure:
cat "somefile" | while read var1 var2; do
# do something with vars 1 and 2
done 3<&1
I experimentally took off the "3<&1" redirect and nothing changed in the execution or behavior... What does the final redirect "3<&1" achieve, and why is it done specifically at the end of the loop?
Below you'll find full init script, it's for Gazzang's zNcrypt service that handles key management for encrypted filesystems. The part I'm interested in occur towards the end of the 'start' and 'stop' cases.
#! /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