Shell 允許你給一個(gè)輸入文件或輸出文件指定一個(gè)文件描述符。這樣可以提高文件讀取和寫入的性能。這類文件描述符被稱為用戶自定義文件描述符。
給一個(gè)輸入文件指定一個(gè)文件描述符的語法如下所示:
exec [n]< file
其中,[n] 即文件描述符,如果不指定 n,則表示標(biāo)準(zhǔn)輸入(即文件描述符 0)。
上述的輸入重定向會(huì)在文件描述符 n 上打開一個(gè)用于讀取的文件 file。
例如,執(zhí)行如下命令,將文件描述符 3 指定給文件 /etc/passwd 以用于從中讀取數(shù)據(jù):
exec 3< /etc/passwd
現(xiàn)在我們就可以在文件描述符 3 上讀取此文件的內(nèi)容,比如,使用 grep 命令來查找指定賬號(hào)的信息:
grep toby <& 3
上述命令中,我們使用了操作符 “<&”,它也是一種重定向操作符,用于復(fù)制輸入文件描述符。其語法如下所示:
[n] <& word
如果 word 是一個(gè)數(shù)字,則用 n 表示的文件描述符被作為文件描述符 word 的副本。如果數(shù)字 word 指定的文件描述符沒有打開以用于讀取,則會(huì)發(fā)生重定向錯(cuò)誤。如果沒有指定 n,則默認(rèn)為標(biāo)準(zhǔn)輸入。
所以,在上述的 grep 命令中,是將文件描述符 3 復(fù)制到標(biāo)準(zhǔn)輸入,而文件 /etc/passwd 又是在文件描述符 3 上打開以用于被命令讀取,因此,grep 命令讀取的實(shí)際是文件描述符 3 的內(nèi)容。
在下面的腳本中,我們從指定的文件描述符來讀取文件的內(nèi)容:
#! /bin/bash
if [ $# -ne 1 ] || [ ! -f $1 ]; then
echo "Usage: $0 <FILEPATH>"
exit 1
fi
# 將腳本的第一個(gè)參數(shù)作為輸入文件,并制定一個(gè)文件描述符 3
exec 3< $1
cat <& 3
# 關(guān)閉文件描述符 3
exec 3<&-
運(yùn)行結(jié)果:

下面我們?cè)偻ㄟ^一個(gè)實(shí)例,來進(jìn)一步學(xué)習(xí)使用 exec 命令指定用于輸入的文件描述符:
#! /bin/bash
# 將標(biāo)準(zhǔn)輸入復(fù)制到文件描述符 6,保存標(biāo)準(zhǔn)輸入
exec 6<&0
# 將文件 /etc/hosts 重定向到標(biāo)準(zhǔn)輸入
exec < /etc/hosts
# 讀取 /etc/hosts 的第一行,并將讀取的內(nèi)容存入變量 a1
read a1
read a2
echo
echo "Following lines read from file."
echo "-------------------------------"
echo $a1
echo $a2
echo; echo; echo
# 現(xiàn)在從文件描述符 6 中恢復(fù)標(biāo)準(zhǔn)輸入,并關(guān)閉文件描述符 6 以釋放給其他進(jìn)行使用
exec <&6 6<&-
echo -n "Enter data: "
read b1
echo "Input read from stdin."
echo "------------------------------"
echo "b1 = $b1"
echo
此腳本的運(yùn)行結(jié)果:

本文參考自 《Linux Shell命令行及腳本編程實(shí)例詳解 》