分享 | 交流
让学习成为一种习惯

Shell 逐行读取文件

1. 问题

先看有问题的代码:

#!/bin/bash
cat file.txt | while read eachline ; do
        echo $eachline
done

上例中,while代码块的输入流已经被管道符重定向至cat的输出,

所以如果在while代码块内,有sed、awk、ssh 等命令时,会在第一次循环时,一次性读取输入流内容的所有行。

这样read命令在第二次运行时,输入流的内容已经是空的,read就读取不到内容,从而结束循环。

2. 解决方法

为了避免上面的问题,可以参考这样的处理方式:

假如,/etc/hosts的内容有

192.168.12.6   host_a
192.168.12.9  host_b
192.168.12.18  host_c
192.168.12.19  host_d

用这段代码处理:

cat /etc/hosts | grep host | while read v1 v2
do
exec 8<& 0 0< /dev/null
ssh $v2 "hostname"
exec 0<& 8 8<& -
done

运行以上代码后,输出结果为:

host_a
host_b
host_c
host_d

3. 原理

FD=文件标示符(File Descriptor)

exec 8<& 0 0< /dev/null?这句会将FD=8的输入重定向到FD=0所使用的输入设备,然后将FD=0的输入重定向到/dev/null。

这样,ssh就不会影响到read在下一次要读取的内容。

exec 0<& 8 8<& -?这句会将FD=0的输入重定向到FD=8所使用的输入设备(也就是cat的输出内容),然后关闭FD=8的输入,使其他程序可以使用FD=8。

未经允许不得转载:留时刻运维网 » Shell 逐行读取文件

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

留时刻 - Linux系统教程,运维经验分享

加入我们给我留言