管道的陷阱

来源:互联网 发布:ubuntu恢复默认输入法 编辑:程序博客网 时间:2024/04/29 09:26

最近写了一个小脚本,没有想到还遇到一个问题,感觉比较隐蔽,和大家分享一下。

 

脚本内容:

 

#!/bin/bash

 

cat $1 | while read id other

do

  flag=0

 

  cat $2 | while read new_id new_other

  do

    if [ $line == $new_line ]

    then

      flag=1

      echo $flag

      break

    fi

  done

 

  echo $flag

  if [$flag -eq 0 ]

  then

    eho $line >> $3

  fi

 

done

 

先解释一下,脚本的目的是从文件1中读取一行的第一列,然后读取文件2中每一行的第一列,如果文件2中第一列包含了文件1中的第一列的内容,则什么都不做,否则就将文件1中这一行的内容写到文件3中。

运行结果却和想象的不一样,不管文件1中一行第一列是否被包含在文件2中,文件1中的每一行都被写入到了文件3中。

调试了一下,发现第一个echo处打印的是1,但是在break之后第二个echo处打印出来就是0了,想了很久也没有搞懂。

后来找了同事一起调,把代码处理成下面这样:

 

#!/bin/bash

 

cat $1 | while read id other

do

  flag=0

 

  while [ 1 ]

  do

      flag=1

      echo $flag

      break

  done

 

  echo $flag

 

done

 

这个时候发现第一个echo打印1,第二个echo也打印1了。所以就怀疑是语句cat $2 | while read new_id new_other造成的原因了。

于是,将读取文件的方式换了一下,程序变为:

 

#!/bin/bash

 

while read id other

do

  flag=0

 

  while read new_id new_other

  do

    if [ $line == $new_line ]

    then

      flag=1

      echo $flag

      break

    fi

  done < $2

 

  echo $flag

  if [$flag -eq 0 ]

  then

    eho $line >> $3

  fi

 

done < $1

 

这样,程序终于正常工作了。

 

没有想到管道还有这个功能,把外部变量的作用域屏蔽掉了。但是在网上搜索了一下,没有找到相应的解释,也可能是自己还没有把shell编程搞透彻。

不管怎样,有一点收获就记下来,分享给大家,也希望有牛人能解释一下,整理出一个规则之类的东东来,以免下次又钻到陷阱里面去了。