代码块重定向
象while, until, 和for循环代码块, 甚至if/then测试结构的代码块, 都可以对stdin进行重定向. 即使函数也可以使用这种重定向方式 要想做到这些, 都要依靠代码块结尾的<操作符.
1.while循环的重定向
Filename=$1
count=0
echo
while [ "$name" != Smith ] # 为什么变量$name要用引号?
do
read name # 从$Filename文件中读取输入, 而不是在stdin中读取输入.
echo $name
let "count += 1"
done <"$Filename" # 重定向stdin到文件$Filename.
2.重定向while循环的另一种形式
# Heiner Steven建议,
#+ 为了避免重定向循环运行在子shell中(老版本的shell会这么做), 最好让重定向循环运行在当前工作区内,
#+ 这样的话, 需要提前进行文件描述符重定向,
#+ 因为变量如果在(子shell上运行的)循环中被修改的话, 循环结束后并不会保存修改后的值.
Filename=$1
exec 3<&0 # 将stdin保存到文件描述符3.
exec 0<"$Filename" # 重定向标准输入.
while [ "$name" != Smith ]
do
read name # 从stdin(现在已经是$Filename了)中读取.
echo $name
let "count += 1"
done # 从文件$Filename中循环读取
exec 0<&3 # 恢复保存的stdin.
exec 3<&- # 关闭临时文件描述符3.
echo; echo "$count names read"; echo
exit 0
3.重定向until循环
Filename=$1
until [ "$name" = Smith ] # 把!=改为=.
do
read name # 从$Filename中读取, 而不是从stdin中读取.
echo $name
done <"$Filename" # 重定向stdin到文件$Filename.
# 结果和前面例子的"while"循环相同.
exit 0
4.重定向for循环
Filename=$1
fi
line_count=`wc $Filename | awk '{ print $1 }'`
# 目标文件的行数.
#
# 此处的代码太过做作, 并且写得很难看,
#+ 但至少展示了"for"循环的stdin可以重定向...
#+ 当然, 你得足够聪明, 才能看得出来.
#
# 更简洁的写法是 line_count=$(wc -l < "$Filename")
for name in `seq $line_count` # "seq"打印出数字序列.
do
read name # 从$Filename中, 而非从stdin中读取.
echo $name
if [ "$name" = Smith ] # 因为用for循环, 所以需要这个多余测试.
then
break
fi
done <"$Filename" # 重定向stdin到文件$Filename.
exit 0
5.重定向for循环(stdin和stdout都进行重定向)
Filename=$1
fi
Savefile=$Filename.new # 保存最终结果的文件名.
FinalName=Jonah # 终止"read"时的名称.
line_count=`wc $Filename | awk '{ print $1 }'` # 目标文件的行数.
for name in `seq $line_count`
do
read name
echo "$name"
if [ "$name" = "$FinalName" ]
then
break
fi
done < "$Filename" > "$Savefile" # 重定向stdin到文件$Filename,
exit 0
6.重定向if/then测试结构
Filename=$1
TRUE=1
if [ "$TRUE" ] # if true 和 if : 都可以.
then
read name
echo $name
fi <"$Filename"
# 只读取了文件的第一行.
# An "if/then"测试结构不能自动地反复地执行, 除非把它们嵌到循环里.
exit 0
7.重定向代码块的stdout, 与"将代码块的输出保存到文件中"具有相同的效果.
here document 是重定向代码块的一个特例.
阅读(473) | 评论(0) | 转发(0) |