zoukankan      html  css  js  c++  java
  • cat file | while read line的问题

    循环中的重定向

    或许你应该在其他脚本中见过下面的这种写法:
    while read line
    do
           …
    done < file
    刚开始看到这种结构时,很难理解< file是如何与循环配合在一起工作的。因为循环内有很多条命令,而我们之前接触的重定向都是为一条命令工作的。这里有一个原则,这个原则掌握好了,这个问题就很简单了:
    对循环重定向的输入可适用于循环中的所有需要从标准输入读取数据的命令;
    对循环重定向的输出可适用于循环中的所有需要向标准输出写入数据的命令;
    当在循环内部显式地使用输入或输出重定向,内部重定向覆盖外部重定向。
    上面的while结构中,read命令是需要从标准输入中读取数据的。我们来详细了解一下read命令的用法吧,这个命令是shell脚本中使用频率最高的命令之一。
    read
    先来看一下read的命令语法:
    read arg1 arg2 arg3 arg4 …
    read是一个用来赋值的命令,它需要从标准输入获得值,然后把这些值按位置依次赋值给变量arg1、arg2、arg3、arg4…,输入的时候以空格作为字段分隔符。
    read的一个最大特性是可以在脚本中产生交互,因为它从标准输入读取数据。read之所以很常用,一是因为我们经常需要赋值,二是因为它可以交互,三是read能够一次给多个变量赋值。
    $ read host ip name
    linux 10.0.0.1 licong
    $ echo $host $ip $name
    linux 10.0.0.1 licong
    $
    可以看到,linux、10.0.0.1、licong分别被赋值给了变量host、ip和name。再看:
    $ read host ip
    linux 10.0.0.1 licong
    $ echo $host
    linux
    $ echo $ip
    10.0.0.1 licong
    $
    当我们输入的字段比变量数目多时,最后一个变量的值将不只一个字段,而是所有剩余的内容;当输入字段比变量数少时,多余的变量将是空值,你可以自己试试。现在我们再来看
    while read line
    do
           …
    done < file
    read通过输入重定向,把file的第一行所有的内容赋值给变量line,循环体内的命令一般包含对变量line的处理;然后循环处理file的第二行、第三行。。。一直到file的最后一行。还记得while根据其后的命令退出状态来判断是否执行循环体吗?是的,read命令也有退出状态,当它从文件file中读到内容时,退出状态为0,循环继续惊醒;当read从文件中读完最后一行后,下次便没有内容可读了,此时read的退出状态为非0,所以循环才会退出。
    另一种也很常见的用法:
    command | while read line
    do
        …
    done
    如果你还记得管道的用法,这个结构应该不难理解吧。command命令的输出作为read循环的输入,这种结构长用于处理超过一行的输出,当然awk也很擅长做这种事。
    APP_FILE=./aabb(这个是多行文件)
    cat $APP_FILE|while read line
    do
        ssh -q $line ls /home/admin
    done
    fail: 只执行了一次,就退出了循环
    这里的问题是所有的内容都一起读取出来写到缓存里面了,让SSH重定向出去了
    注意:

    1. ssh命令在每次执行时,会读取所有的标准输入中的内容。

    cat file |ssh 1.1.1.1 cat  会读取所有文件的内容

    2. 对于while循环,当按照如下方式使用时:

        cat file | while read line

    这里使用重定向,将文件内容输入到while命令,while命令每次使用read从输入中读取一行数据。

    问题就在这里,如果在while循环中调用了ssh命令,那么ssh就会把当前输入中所有的数据读走,也就是cat file重定向给while命令的数据,都被ssh命令读走了,以至于下次循环的时候,read读到的内容为空,导致循环提前结束。

    解决这个问题两种方式

    1. ssh -n 使用-n参数

    2. ssh xxxx < /dev/null重定向shell命令的输入

    主要参数说明:

    -l 指定登入用户

    -p 设置端口号

    -f 后台运行,并推荐加上 -n 参数

    -n 将标准输入重定向到 /dev/null,防止读取标准输入

    -N 不执行远程命令,只做端口转发

    -q 安静模式,忽略一切对话和错误提示

    -T 禁用伪终端配置
    参考文章
    http://blog.163.com/clevertanglei900@126/blog/static/11135225920118742327322/
     

    一 、重定向法;管道法: cat $FILENAME | while read LINE

    Function While_read_LINE(){

    cat $FILENAME | while read LINE

    do

    echo $LINE

    done

    }

             注释:我只所有把这种方式叫做管道法,相比大家应该可以看出来了吧。当遇见管道的时候管道左边的命令的输出会作为管道右边命令的输入然后被输入出来。

    二、实例

    1、pri.sh

    #!/bin/bash
    
    cat ~/xieco/dirls | while read dd
    do
      echo "chown -R test:test ${dd}"
      chown -R deuser:deuser ${dd}
    done
     

    2、dirr

    /usr/local/htdocs/dcserver/utilserver/
    /usr/local/configs/

    ### 题目要求
    计算文档a.txt中每一行中出现的数字个数并且要计算一下整个文档中一共出现了几个数字。例如a.txt内容如下:
    12aa*lkjskdj
    alskdflkskdjflkjj
    我们脚本名字为 ncount.sh, 运行它时:
    bash ncount.sh a.txt
    输出结果应该为:
    2
    0
    sum:2

    #### 参考答案
    ```

    #!/bin/bash
    sum=0
    while read line
    do
    line_n=`echo $line|sed 's/[^0-9]//g'|wc -L`
    echo $line_n
    sum=$[$sum+$line_n]
    done < $1
    echo "sum:$sum"

      

    当我们输入的字段比变量数目多时,最后一个变量的值将不只一个字段,而是所有剩余的内容;当输入字段比变量数少时,多余的变量将是空值,你可以自己试试。现在我们再来看
    while read line
    do
           …
    done < file
    read通过输入重定向,把file的第一行所有的内容赋值给变量line,循环体内的命令一般包含对变量line的处理;然后循环处理file的第二行、第三行。。。一直到file的最后一行。还记得while根据其后的命令退出状态来判断是否执行循环体吗?是的,read命令也有退出状态,当它从文件file中读到内容时,退出状态为0,循环继续惊醒;当read从文件中读完最后一行后,下次便没有内容可读了,此时read的退出状态为非0,所以循环才会退出。
    另一种也很常见的用法:
    command | while read line
    do
        …
    done
    如果你还记得管道的用法,这个结构应该不难理解吧。command命令的输出作为read循环的输入,这种结构长用于处理超过一行的输出,当然awk也很擅长做这种事。
  • 相关阅读:
    Application和Page详解
    Session解析
    CSS设置技巧
    CSS布局模型
    CSS盒模型
    JAVA -Xms -Xmx -XX:PermSize -XX:MaxPermSize 区别
    设计模式——单例模式
    设计模式——工厂模式
    Go语言学习
    每周一个设计模式
  • 原文地址:https://www.cnblogs.com/klb561/p/11241651.html
Copyright © 2011-2022 走看看