循环中的重定向

或许你应该在其他脚本中见过下面的这种写法:
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也很擅长做这种事。

cat file | while read line的问题的更多相关文章

  1. How to build .apk file from command line(转)

    How to build .apk file from command line Created on Wednesday, 29 June 2011 14:32 If you don’t want ...

  2. 解决Warning: unlink(/storage/cache/cache.catalog.language.1556158719): No such file or directory in /system/library/cache/file.php on line 68问题

    ytkah在调试opencart项目时提示Warning: unlink(/storage/cache/cache.catalog.language.1556158719): No such file ...

  3. SyntaxError: Non-UTF-8 code starting with '\xe5' in file ***.py on line 105, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for

    用charles抓包时, 对抓到的html,放到pycharm中解析, 结果报错: SyntaxError: Non-UTF-8 code starting with '\xe5' in file * ...

  4. cat > file << EOF 与 cat > file << -

    当我们在使用kickstart 的时候,会遇到写网卡配置文件的情况,这时候我们使用cat > file << EOF 命令等,可以从标准输入中接受输入并保存到 file 文件中. c ...

  5. 安装Phoenix时./sqlline.py执行报错File "./sqlline.py", line 27, in <module> import argparse ImportError: No module named argparse解决办法(图文详解)

    不多说,直接上干货! 前期博客 Apache版Phoenix的安装(图文详解) 问题现象 Traceback (most recent call last): File , in <module ...

  6. (C++) Assertion failed: !"Bad error code", file VMem.c, line 715

    (C++) Assertion failed: !"Bad error code", file VMem.c, line 715 Misc error. myInterface F ...

  7. Traceback (most recent call last): File "setup.py", line 22, in <module> execfile(join(CURDIR, 'src', 'SSHLibrary', 'version.py')) NameError: name 'execfile' is not defined

    在python3环境下安装robotframework-SSHLibraray报错: Traceback (most recent call last): File "setup.py&qu ...

  8. mysql InnoDB: Assertion failure in thread xxxx in file ut0mem.cc line 105

    mysql InnoDB: Assertion failure in thread xxxx in file ut0mem.cc line 105 错误信息 InnoDB: Assertion fai ...

  9. cat > file << EOF 的用法

    cat> 文件名<<eof 用来创建文件在这之后输入任何东西 都是在 文件里的输入完成之后EOF结尾 代表结束比如cat > 1.txt <<eof12345eof ...

随机推荐

  1. 七年开发经验详解JVM的GC 算法

    概述 GC 是 JVM 自带的功能,它能够自动回收对象,清理内存,这是 Java 语言的一大优势,但是GC绝不仅伴随着Java,相反,GC历史比Java更悠久.关于GC,我认为有四个问题需要解决: 为 ...

  2. 记一次B类地址子网划分

    说明:一般内网地址,没有要求严格的划分之类的.需要按要求严格划分一般都是公网地址 温馨提醒:由于笔者功底不是很深厚,只能说我们保证把数算对用相对简单的方法 现有一个公网ip,B类地址130.3.0.0 ...

  3. 版本问题---Bazel与tensorflow的对应关系

    源码安装tf的时候,会用到Bazel,版本不对应,后面会引起好多麻烦. echo "deb [arch=amd64] http://storage.googleapis.com/bazel- ...

  4. vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.

    默认,webpack无法打包.vue文件,需要安装 相关的loader: cnpm i vue-loader vue-template-compiler -D 提示以下错误信息: Module Err ...

  5. 14 webpack中url-loader的使用

    默认情况下,webpack无法处理css文件中的url地址,不管是图片还是字体库,只要是URL地址,都处理不了,需要第三方loader 1.安装loader cnpm i url-loader fil ...

  6. 8 loader - 配置处理css样式表的第三方loader

    // 使用import语法,导入css样式表 import './css/index.css' // 注意:webpack,默认只能打包处理JS类型的文件,无法处理其它的非JS类型的文件: // 如果 ...

  7. git 将master分支合到自己的开发分支

    背景: 一般开发自己的分支都是从最新的master上拉取,但中间master会有改动,此时需要将最新的master合到自己的分支中 命令: 1. 查看当前的分支,星号标识为当前分支:(如果查询结果有m ...

  8. ask confirm shell

    #/bin/bash BASEDIR=$(cd $() && pwd) cd $BASEDIR>/dev/null usage="Usage: $0 -o/--org ...

  9. UWB DWM1000 开源项目框架

    UWB 目前比较火热,不论国内还是国外目前都掀起一股热潮. 但是实际工程代码很少,开源代码更少. 目前代码主要有 1 DecaWave Release的定位源码,代码基于TWR,一个非常大的状态机. ...

  10. 建立component的多种方法

    vue之component 在Vue.js中定义组件模板的七种方式 终于搞懂了vue 的 render 函数(一) Vuejs2.0学习(Render函数,createElement,vm.$slot ...