zoukankan      html  css  js  c++  java
  • Linux Shell重定向(输入输出重定向)精讲

    Linux Shell 重定向分为两种,一种输入重定向,一种是输出重定向;从字面上理解,输入输出重定向就是「改变输入与输出的方向」的意思。
    
    那么,什么是输入输出方向呢?标准的输入输出方向又是什么呢?
    
    一般情况下,我们都是从键盘读取用户输入的数据,然后再把数据拿到程序(C语言程序、Shell 脚本程序等)中使用;这就是标准的输入方向,也就是从键盘到程序。
    
    反过来说,程序中也会产生数据,这些数据一般都是直接呈现到显示器上,这就是标准的输出方向,也就是从程序到显示器。
    
    我们可以把观点提炼一下,其实输入输出方向就是数据的流动方向:
    输入方向就是数据从哪里流向程序。数据默认从键盘流向程序,如果改变了它的方向,数据就从其它地方流入,这就是输入重定向。
    输出方向就是数据从程序流向哪里。数据默认从程序流向显示器,如果改变了它的方向,数据就流向其它地方,这就是输出重定向。
    硬件设备和文件描述符
    计算机的硬件设备有很多,常见的输入设备有键盘、鼠标、麦克风、手写板等,输出设备有显示器、投影仪、打印机等。不过,在 Linux 中,标准输入设备指的是键盘,标准输出设备指的是显示器。
    
    Linux 中一切皆文件,包括标准输入设备(键盘)和标准输出设备(显示器)在内的所有计算机硬件都是文件。
    
    为了表示和区分已经打开的文件,Linux 会给每个文件分配一个 ID,这个 ID 就是一个整数,被称为文件描述符(File Descriptor)。

    表1:与输入输出有关的文件描述符

    文件描述符文件名类型硬件
    0 stdin 标准输入文件 键盘
    1 stdout 标准输出文件 显示器
    2 stderr 标准错误输出文件 显示器
    Linux 程序在执行任何形式的 I/O 操作时,都是在读取或者写入一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数,它的背后可能是一个硬盘上的普通文件、FIFO、管道、终端、键盘、显示器,甚至是一个网络连接。
    
    stdin、stdout、stderr 默认都是打开的,在重定向的过程中,0、1、2 这三个文件描述符可以直接使用。
    Linux Shell 输出重定向
    输出重定向是指命令的结果不再输出到显示器上,而是输出到其它地方,一般是文件中。这样做的最大好处就是把命令的结果保存起来,当我们需要的时候可以随时查询。Bash 支持的输出重定向符号如下表所示。
    

      表2:Bash 支持的输出重定向符号

     在输出重定向中,>代表的是覆盖,>>代表的是追加。

    注意
    输出重定向的完整写法其实是fd>file或者fd>>file,其中 fd 表示文件描述符,如果不写,默认为 1,也就是标准输出文件。
    
    当文件描述符为 1 时,一般都省略不写,如上表所示;当然,如果你愿意,也可以将command >file写作command 1>file,但这样做是多此一举。
    
    当文件描述符为大于 1 的值时,比如 2,就必须写上。
    
    需要重点说明的是,fd和>之间不能有空格,否则 Shell 会解析失败;>和file之间的空格可有可无。为了保持一致,我习惯在>两边都不加空格。
    

     下面的语句是一个反面教材: 

    echo "c.biancheng.net" 1 >log.txt

    注意1>之间的空格。echo 命令的输出结果是c.biancheng.net,我们的初衷是将输出结果重定向到 log.txt,但是当你打开 log.txt 文件后,发现文件的内容为c.biancheng.net 1,这就是多余的空格导致的解析错误。也就是说,Shell 将该条语句理解成了下面的形式:

    echo "c.biancheng.net" 1 1>log.txt

    输出重定向举例

    【实例1】将 echo 命令的输出结果以追加的方式写入到 demo.txt 文件中。

    #!/bin/bash
    for str in "C语言中文网" "http://c.biancheng.net/" "成立7年了" "日IP数万"
    do
        echo $str >>demo.txt  #将输入结果以追加的方式重定向到文件
    done
    
    运行以上脚本,使用cat demo.txt查看文件内容,显示如下:
    C语言中文网
    http://c.biancheng.net/
    成立7年了
    日IP数万

    【实例2】将ls -l命令的输出结果重定向到文件中。

    [c.biancheng.net]$ ls -l  #先预览一下输出结果
    总用量 16
    drwxr-xr-x. 2 root     root      21 7月   1 2016 abc
    -rw-r--r--. 1 mozhiyan mozhiyan 399 3月  11 17:12 demo.sh
    -rw-rw-r--. 1 mozhiyan mozhiyan  67 3月  22 17:16 demo.txt
    -rw-rw-r--. 1 mozhiyan mozhiyan 278 3月  16 17:17 main.c
    -rwxr-xr-x. 1 mozhiyan mozhiyan 187 3月  22 17:16 test.sh
    [c.biancheng.net]$ ls -l >demo.txt  #重定向
    [c.biancheng.net]$ cat demo.txt  #查看文件内容
    总用量 12
    drwxr-xr-x. 2 root     root      21 7月   1 2016 abc
    -rw-r--r--. 1 mozhiyan mozhiyan 399 3月  11 17:12 demo.sh
    -rw-rw-r--. 1 mozhiyan mozhiyan   0 3月  22 17:21 demo.txt
    -rw-rw-r--. 1 mozhiyan mozhiyan 278 3月  16 17:17 main.c
    -rwxr-xr-x. 1 mozhiyan mozhiyan 187 3月  22 17:16 test.sh

    错误输出重定向举例

    命令正确执行是没有错误信息的,我们必须刻意地让命令执行出错,如下所示:

    [c.biancheng.net]$ ls java  #先预览一下错误信息
    ls: 无法访问java: 没有那个文件或目录
    [c.biancheng.net]$ ls java 2>err.log  #重定向
    [c.biancheng.net]$ cat err.log  #查看文件
    ls: 无法访问java: 没有那个文件或目录

    正确输出和错误信息同时保存

    【实例1】把正确结果和错误信息都保存到一个文件中,例如:

    [c.biancheng.net]$ ls -l >out.log 2>&1
    [c.biancheng.net]$ ls java >>out.log 2>&1
    [c.biancheng.net]$ cat out.log
    总用量 12
    drwxr-xr-x. 2 root     root      21 7月   1 2016 abc
    -rw-r--r--. 1 mozhiyan mozhiyan 399 3月  11 17:12 demo.sh
    -rw-rw-r--. 1 mozhiyan mozhiyan 278 3月  16 17:17 main.c
    -rw-rw-r--. 1 mozhiyan mozhiyan   0 3月  22 17:39 out.log
    -rwxr-xr-x. 1 mozhiyan mozhiyan 187 3月  22 17:16 test.sh
    ls: 无法访问java: 没有那个文件或目录

    out.log 的最后一行是错误信息,其它行都是正确的输出结果。

    【实例2】上面的实例将正确结果和错误信息都写入同一个文件中,这样会导致视觉上的混乱,不利于以后的检索,所以我建议把正确结果和错误信息分开保存到不同的文件中,也即写成下面的形式:

    ls -l >>out.log 2>>err.log

    这样一来,正确的输出结果会写入到 out.log,而错误的信息则会写入到 err.log。

    /dev/null 文件

    如果你既不想把命令的输出结果保存到文件,也不想把命令的输出结果显示到屏幕上,干扰命令的执行,那么可以把命令的所有结果重定向到 /dev/null 文件中。如下所示:

    ls -l &>/dev/null
    

    大家可以把 /dev/null 当成 Linux 系统的垃圾箱,任何放入垃圾箱的数据都会被丢弃,不能恢复。

    Linux Shell 输入重定向

    输入重定向就是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件作为命令的输入。  

     表3:Bash 支持的输出重定向符号

    符号说明
    command <file 将 file 文件中的内容作为 command 的输入。
    command <<END 从标准输入(键盘)中读取数据,直到遇见分界符 END 才停止(分界符可以是任意的字符串,用户自己定义)。
    command <file1 >file2 将 file1 作为 command 的输入,并将 command 的处理结果输出到 file2。

    和输出重定向类似,输入重定向的完整写法是fd<file,其中 fd 表示文件描述符,如果不写,默认为 0,也就是标准输入文件。

    输入重定向举例

    【示例1】统计文档中有多少行文字。

    Linux wc 命令可以用来对文本进行统计,包括单词个数、行数、字节数,它的用法如下:

    wc  [选项]  [文件名]
    

     其中,-c选项统计字节数,-w选项统计单词数,-l选项统计行数。

    统计 readme.txt 文件中有多少行文本: 

    [c.biancheng.net]$ cat readme.txt  #预览一下文件内容
    C语言中文网
    http://c.biancheng.net/
    成立7年了
    日IP数万
    [c.biancheng.net]$ wc -l <readme.txt  #输入重定向
    4

     【实例2】逐行读取文件内容。

    #!/bin/bash
    
    while read str; do
        echo $str
    done <readme.txt
    运行结果:
    C语言中文网
    http://c.biancheng.net/
    成立7年了
    日IP数万

    这种写法叫做代码块重定向,也就是把一组命令同时重定向到一个文件,我们将在《Shell代码块重定向》一节中详细讲解。

    【实例3】统计用户在终端输入的文本的行数。

    此处我们使用输入重定向符号<<,这个符号的作用是使用特定的分界符作为命令输入的结束标志,而不使用 Ctrl+D 键。

    [c.biancheng.net]$ wc -l <<END
    > 123
    > 789
    > abc
    > xyz
    > END
    4

    wc 命令会一直等待用输入,直到遇见分界符 END 才结束读取。

    <<之后的分界符可以自由定义,只要再碰到相同的分界符,两个分界符之间的内容将作为命令的输入(不包括分界符本身)。

    源地址:http://c.biancheng.net/view/942.html

  • 相关阅读:
    在Flex or AIR中检测你的网络连接是否正常
    设置Adobe Air应用程序属性
    airMeeting
    用Adobe Flex3开发AIR应用程序–入门指南
    Adobe Flash Player 9.0.124 的安全策略更改
    分发,安装和运行AIR应用程序
    永远置于顶层(always on top)的AIR应用
    翻译:SWFObject 2.0官方文档
    C#温故而知新学习系列之.NET框架高级特性—概述.NET框架中的反射(一)
    C#温故而知新学习系列之字符串处理—指定字符串的显示格式(一)
  • 原文地址:https://www.cnblogs.com/w-j-q/p/14832492.html
Copyright © 2011-2022 走看看