exec
exec 命令会将stdin重定向到文件中. 从这句开始, 后边的输入就都来自于这个文件了, 而不是标准输入了(通常都是键盘输入). 这样就提供了一种按行读取文件的方法, 并且可以使用sed 和/或 awk来对每一行进行分析.
使用exec重定向标准输入:
1 #!/bin/bash
2 # 使用'exec'重定向标准输入.
3
4
5 exec 6<&0 # 将文件描述符#6与stdin链接起来.
6 # 保存了stdin.
7
8 exec < data-file # stdin被文件"data-file"所代替.
9
10 read a1 # 读取文件"data-file"的第一行.
11 read a2 # 读取文件"data-file"的第二行.
12
13 echo
14 echo "Following lines read from file."
15 echo "-------------------------------"
16 echo $a1
17 echo $a2
18
19 echo; echo; echo
20
21 exec 0<&6 6<&-
22 # 现在将stdin从fd #6中恢复, 因为刚才我们把stdin重定向到#6了,
23 #+ 然后关闭fd #6 ( 6<&- ), 好让这个描述符继续被其他进程所使用.
24 #
25 # <&6 6<&- 这么做也可以.
26
27 echo -n "Enter data "
28 read b1 # 现在"read"已经恢复正常了, 就是从stdin中读取.
29 echo "Input read from stdin."
30 echo "----------------------"
31 echo "b1 = $b1"
32
33 echo
34
35 exit 0
例如可以这样读文件:
exec 3<>test.sh;
#打开test.sh可读写操作,与文件描述符3绑定
while read line<&3
do
echo $line;
done
#循环读取文件描述符3(读取的是test.sh内容)
exec 3>&-
exec 3<&-
#关闭文件的,输入,输出绑定
当然一般我们可以直接重定向文件到一个代码块,相当于重定向到这个代码块的标准输入。
重定向到代码块
通常我们可以将利用将代码块的输入输出重定向的方法实现一些对于文件的操作。
例如:
# while的重定向
while [ "$name" != Smith ]
do
read name
echo $name
done <"$Filename"
# 以上结构也可以这样写
exec 3<&0 # 把标准输入绑定到文件描述符3,以便稍后恢复
exec 0<"$Filename" # 重定向标准输入为这个文件
while [ "$name" != Smith ]
do
read name
echo $name
done
exec 0<&3 # 恢复标准输入
exec 3<&- # 关闭文件描述符3以供后续使用
# until的重定向
until [ "$name" = Smith ]
do
read name
echo "$name"
done <"$Filename"
# for循环的重定向
lineCount=`wc $Filename | awk '{print $1}'` # 统计文件的行数
for name in `seq $lineCount`
do
read name
echo $name
if [ "$name" = Smith ] # 循环到Smith的时候就退出循环
then
break
fi
done <"$Filename"
# if/then结构的重定向
if :
then
read name
echo "$name"
fi <"$Filename" # 这个重定向只读了文件中的一行