cat file | while read line的问题

循环中的重定向

或许你应该在其余脚本中见过下面的这种写法:
while read line
do
       …
done < file
刚开始看到这种结构时,很难理解< file是如何与循环配合在一块儿工做的。由于循环内有不少条命令,而咱们以前接触的重定向都是为一条命令工做的。这里有一个原则,这个原则掌握好了,这个问题就很简单了:
对循环重定向的输入可适用于循环中的全部须要从标准输入读取数据的命令;
对循环重定向的输出可适用于循环中的全部须要向标准输出写入数据的命令;
当在循环内部显式地使用输入或输出重定向,内部重定向覆盖外部重定向。
上面的while结构中,read命令是须要从标准输入中读取数据的。咱们来详细了解一下read命令的用法吧,这个命令是shell脚本中使用频率最高的命令之一。
read
先来看一下read的命令语法:
read arg1 arg2 arg3 arg4 …
read是一个用来赋值的命令,它须要从标准输入得到值,而后把这些值按位置依次赋值给变量arg一、arg二、arg三、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.一、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命令在每次执行时,会读取全部的标准输入中的内容。html

cat file |ssh 1.1.1.1 cat  会读取全部文件的内容linux

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

    cat file | while read line缓存

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

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

解决这个问题两种方式post

1. ssh -n 使用-n参数spa

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

主要参数说明:

-l 指定登入用户server

-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

}

         注释:我只全部把这种方式叫作管道法,相比你们应该能够看出来了吧。当碰见管道的时候管道左边的命令的输出会做为管道右边命令的输入而后被输入出来。

2、实例

一、pri.sh

#!/bin/bash

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

 

二、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也很擅长作这种事。
相关文章
相关标签/搜索