先看一段簡化過的BASH SHELL代碼
TODAY=`date +%Y%m%d`
SUFFIX="tar"
CONF=the_config_file
i=0
while read HOST SRCPATH DSTPATH
do
(( i++ ))
if [ "X${HOST:0:1}" = "X#" -o ${#DSTPATH} -eq 0 ]
then
#忽略注釋行及少于3個項的記錄
else
ssh ${HOST} "tar c ${SRCPATH}" >${DSTPATH}.${TODAY}.${SUFFIX} 2>/dev/null
fi
done < $CONF
作者的本意是通過腳本讀取配置檔案$CONF,然後打包備份$CONF中指定的檔案,但執行後發現程式在成功備份$CONF中指定的第一個檔案後即退出……
跟蹤後發現read在備份完第一個檔案後就再讀不到任何資料,是以while循環結束--也就是說,
通過重定向$CONF檔案傳給标準輸入的資料被
這個指令提前吃掉了。
将其改為
ssh ${HOST} "tar c ${SRCPATH}" >${DSTPATH}.${TODAY}.${SUFFIX} 2>/dev/null </dev/null
将ssh的标準輸入重定向到/dev/null,程式正常備份所有$CONF中指定的檔案。
--------------------------------------------------------
結論:
while read時,要注意那些處理标準輸入的指令,例如
cat,mail,ssh,grep,sed,tr,awk……(幾乎所有支援流文本處理的指令都包含在内)