zoukankan      html  css  js  c++  java
  • (四)Linux Shell编程——输入输出重定向

    Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示。一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器。

    1. 输出重定向

    命令的输出不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出重定向。

    命令输出重定向的语法为:

    command > file

    如:将用户信息输出到 test.sh文件中(test.sh文件中含有内容)

    [root@centoszang testShell]# ls
    choose.sh  menuChoose  myShell.sh  test.sh
    [root@centoszang testShell]# who > test.sh
    [root@centoszang testShell]# cat test.sh 
    root     tty1         2018-06-18 08:44 (:0)
    root     pts/0        2018-06-18 14:55 (192.168.177.1)

    可以看到,输出重定向会覆盖文件内容,如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾

    [root@centoszang testShell]# echo "Hello EveryOne" >> test.sh
    [root@centoszang testShell]# cat test.sh 
    root     tty1         2018-06-18 08:44 (:0)
    root     pts/0        2018-06-18 14:55 (192.168.177.1)
    Hello EveryOne

    2. 输入重定向

    和输出重定向一样,Unix 命令也可以从文件获取输入。

    command < file

     这样,本来需要从键盘获取输入的命令会转移到文件读取内容。

    [root@centoszang testShell]# wc -l test.sh    #计算 test.sh 文件中的行数
    3 test.sh
    [root@centoszang testShell]# wc -l < test.sh
    3

    上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。

    3. 重定向深入讲解

    3.1 基本介绍

    一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

    • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
    • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
    • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

    默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

    如果希望 stderr 重定向或追加到 file,可以按照如下语法:

    command 2> file   #重定向
    command 2 >> file   #追加

    如下代码是将标准错误信息(stderr)也输出到log文件

    将 stdout 和 stderr 合并后重定向到 log

    重定向到某个文件描述符时,必须在文件描述符前面添加 & 符号。必须这样的原因:类似1,2这样的文件描述符也是标准的Linux文件名称,添加 & 符号以做区分。

    3.2 两种(合并)重定向的区别

    考虑当我们将stdout和stderr输出时,command > file 2> file command > file 2>&1 这两种语法效果一样吗?

    效果貌似一样:因为不管是command产生的标准输出信息还是标准错误信息都重定向到了file文件里。确实如此,但也有让人意料之外的地方:

    command > file 2> file 命令把STDOUT和STDERR都直接送到file文件中,file文件会被打开两次,这样STDOUT和STDERR会相互覆盖。该命令执行时相当于两个进程同时向同一个文件中写数据,你写你的,我写我的,也不进行同步,写完拉倒。打开文件一看,数据重叠,乱七八糟。

    command > file 2>&1 命令把STDOUT直接送往file文件,而STDERR经由STDOUT的通道把数据信息送到file文件中。此时,file文件只被打开了一次,因此标准输出数据和标准错误数据不会相互覆盖,而是井然有序。

    从I/O效率上来说,command > file 2> file 相比于 command > file 2>&1 要低,而且会出现数据相互覆盖的情况。因此,我们一般会使用后面这条命令。

    3.3 可用的重定向命令列表

    3.4 在同一命令中进行多次输出重定向

     如果我们在同一个命令中进行了多次输出重定向操作,会出现什么情况呢?最终命令的输出会重定向到最后一次重定向的位置。

     

    echo hello world > log.txt 1>/dev/tty1 2>&1 命令首先把标准输出重定向到log.txt文件,由于当前目录下并不存在该文件,因此会创建该文件,并把文件清空;接着命令又把标准输出重定向到了终端显示器;最后又把标准错误重定向到了标准输出。因此命令的输出还是被发送到了终端显示器上,命令结束,文件关闭,结果log.txt文件里什么数据都没有写入,只是创建了一个空白的文件。

    4. Here Document

    Here Document 目前没有统一的翻译,这里暂译为”嵌入文档“。Here Document 是 Shell 中的一种特殊的重定向方式。

    语法:

    command << delimiter
        document
    delimiter

    它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。

    注意:

    • 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
    • 开始的delimiter前后的空格会被忽略掉。

    在shell脚本中调用vi编辑器,输入的内容由here document来提供。

    #! /bin/bash
    vi abc.txt <<EOF
    i                        #进入insert模式
    Here is a document!      #输入文本内容
    ^[                       #这个符号是在Ctrl+v下按ESC键,意为按下ESC退出编辑模式
    :wq                      #保存退出
    EOF

    需要注意的是,vi编辑器为交互式编辑器,一般不用在shell脚本中使用,除非有特殊需求。一般在shell脚本中都调用ed编辑器。

    5. /dev/null 文件

     如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null。

    语法:

    command > /dev/null

    /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到”禁止输出“的效果。在只想测试命令而不想有任何输出时较有用。

    command > /dev/null 2>&1   #屏蔽 stdout 和 stderr

    另外,在只想删除文件内容,而不删除文件时,可以使用如下方法

    参考:

    https://www.cnblogs.com/pyhou/p/7650938.html

    http://blog.51cto.com/callmebb/1300348

  • 相关阅读:
    Raspberry Pi + ArchLinux:网络dhcp不稳定,经常无法获取IP地址
    Chromium OS相比Chrome OS缩水的地方
    ssh config配置更新
    ktouch w619: Dump boot.img和system.img,然后做成recovery可用的刷机zip包
    mmap: invalid argument & MAP_PRIVATE
    Ubuntu 12.04 fcitx已经可以aptget,并且默认是是Google拼音的词库
    epoll_create, epoll_ctl和epoll_wait 实例讲解
    VM上安装Redhat无法选包
    关于Segmentation fault (core dumped)几个简单问题的整理
    Linux字符串转换函数汇总
  • 原文地址:https://www.cnblogs.com/zjfjava/p/9195522.html
Copyright © 2011-2022 走看看