shell read命令的一个坑

shell read命令

使用read命令循环读取文件,按行进行处理时经常用到read命令:

1
2
3
4
while read line;
do
echo $line
done < filename

这样做要保证filename文件的内容在读取的时候不会变化,否则可能会与你的处理逻辑不符合,比如

1
2
3
4
5
while read line;
do
mount_point=$(echo $line | awk '{if($3~/nfs/)next}{print $2}')
umount $mount_point
done < /etc/mtab

上述简陋的脚本想umount当前挂载的nfs客户端,但是如果有多个nfs挂载,会漏掉一些,这是因为在umount结束后
/etc/mtab文件也变了,umount的nfs相应的行没了,read按上一次记录的行继续读就出现了问题。

所以这样按行读要确保读的文件至少中间的行不要变化,简单的规避方法是cat filename | while read的方式,但这样
最好filename文件不大,不然很耗内存还可能overflow。