zoukankan      html  css  js  c++  java
  • [Linux]基本I/O重定向

    在我们设置定时任务的时候经常会使用标准输出和标准错误输出。这个在Linux是一个非常重要的概念,而且这个很有用。程序应该有数据库的来源端、数据的目的端,以及报告问题的地方,它们被称为标准输入、标准输出以及标准错误输出。

     
    程序启动的时候,默认情况下,标准输出、输入都会已经打开,且已准备好供其使用。我们使用Xshell连接并登陆上服务器的时候,默认下终端就是标准输入、输出端。可以试试cat命令。
    $ cat                                  #未指定任何的参数是,读取默认的标准输入、写入到默认的标准输出
    建华是可以玩耍的小伙伴                    #用户输入(此时终端默认是标准输入)
    建华是可以玩耍的小伙伴                    #程序将内容输出到标准输出(此时终端默认为标准输出)
    ^D                                     #输入Ctrl-D 告诉程序文件结尾
    重定向与管道
    Shell提供了数种语法,可以修改默认的IO的来源端和目的端,就是标准输入和输出的地方。
    < 修改标准输入 sort < ucid.txt 默认下,标准输入为终端,此时可以更改为你想要的地方
    <<   Command << delimiter 从标准输入中读入,直到遇到delimiter分割符
    > 修改标准输出 ls -l > listinfo.txt 默认下,标准输出为终端,此时可以修改默认输出的地方。譬如可以将标准输出的内容写在文件中。
    如果文件已存在,会被覆盖掉。
    >>  输出附件到文件 ls -l >> listinfo.txt 与[>]不一样的是,[>]会清空原来的内容,而[>>]只是将标准输出追加到文件结尾处。
    | 建立管道 program1 | program2 1. program1的标准输出为program2的标准输入;
    2. 管道的执行效率比使用临时文件的程序起码高一个数量级;
     
    [<]例子
    场景:对文件内容的信息进行排序
    [nemo@name tool]$ cat show.txt
    7291418
    2233803
    8031001
    1258962
    [weiyg@name tool]$ sort < show.txt
    1258962
    2233803
    7291418
    8031001
    [>]例子
    场景:打印内容到文件
    [weiyg@name script]$ ll
    total 20
    -rw-rw-r--. 1 weiyg weiyg 254 Dec 31 13:45 ssh.rb
    -rw-r--r--. 1 weiyg weiyg 476 Dec 30 11:48 sshx.rb
    -rw-rw-r--. 1 weiyg weiyg  12 Dec 26 16:57 test.rb
    [weiyg@name script]$ ls -l > listinfo.txt
    [weiyg@name script]$ cat listinfo.txt 
    total 20
    -rw-rw-r--. 1 weiyg weiyg   0 Jan 22 21:35 listinfo.txt
    -rw-rw-r--. 1 weiyg weiyg 254 Dec 31 13:45 ssh.rb
    -rw-r--r--. 1 weiyg weiyg 476 Dec 30 11:48 sshx.rb
    -rw-rw-r--. 1 weiyg weiyg  12 Dec 26 16:57 test.rb
    在定时任务上面经常使用。因为定时任务执行的内容,不会打印到终端。如果需要查看结果的话就很麻烦。而打印到文件中的话,随时都可以查看了。不过这里往往用[>>]追加比较多。
     
    [>>]例子
    没啥好说的,跟[>]就是一个[>]会覆盖原有的文件,而[>>]只是追加。
     
    [|]管道例子
    场景:查询id为19217xxxx的玩家在1月15日使用道具的日志
    [weiyg@name flash]$ bzcat *useprop.log.2014-01-15.bz2 |grep '19217xxxx'
    1389717003317|19217xxxx|2|304|305|0|
    1389717005097|19217xxxx|2|303|304|0|

    这是查询游戏日志的一个例子。默认下,系统会将游戏5天前的日志进行打包压缩。而此时需要查询5天前的日志的话,使用上面的方法无论在效率上还是方便上,管道都有使用临时文件无法比拟的又是。当然使用下面的方法:

    [weiyg@name flash]$ bzcat *useprop.log.2014-01-15.bz2 > tem.log
    [weiyg@name flash]$ grep '19217xxxx' tem.log
    1389717003317|19217xxxx|2|304|305|0|
    1389717005097|19217xxxx|2|303|304|0|
    也可以达到相同的结果,但相比使用管道,一、需要使用临时文件,读写在磁盘需要时间;二、临时文件还需要手动删除,比较麻烦。
    注:bzcat 可以直接显示压缩文件的内容
     
    特殊文件:/dev/null 与/dev/tty
    /dev/null  传送到此文件的数据都会被系统丢掉,,就是输出到一个空设备的意思。
    /dev/tty   程序打开此文件时,Linux会自动将它重定向到一个终端。
     
    文件描述符
    在定时任务,我们经常在重定向的时候,喜欢这样操作。
    33 1 * * * /home/weiyg/crontab/clear_logs.sh > /dev/null 2>&1
    后面的 2>&1是什么意思呢,这里就要理解文件描述符和绑定重定向的概念了。
    文件 文件描述符
    输入文件——标准输入 0(默认为终端(网上有说默认为键盘的))
    输出文件——标准输出 1(默认为终端)
    错误输出文件——标准错误 2(默认为终端)
    绑定重定向
    Commond >&m 标准输出重定向到文件描述符m中
    Command <&- 关闭标准输入
    Command 0>&- 关闭标准输出
     
    此时我们再去理解[2>&1],就容易多了。[2]是标准错误的文件描述符,而[>&1]的意思重定向到标准输出。那么定时任务的解释就是,将[clear_logs.sh]执行的标准输出和标准错误重定向到[/dev/null](就是丢掉输出的内容)。
    我是这样理解(不一定正确)上面的定时任务的(分2部分):
    clear_logs.sh > /dev/null     #将clear_logs.sh执行的标准输出输出到/dev/null
    clear_logs.sh 2> /dev/null    #将clear_logs.sh执行的标准错误输出到/dev/null,只是clear_logs.sh不是执行了2次,只是1次。这里的&1代表的就是/dev/null
     //-----------------------
    以上为本次学习I/O重定向的笔记。

    参考资料:1. 《Shell脚本学习指南》 Arnold Robbins & Nelson H.F. Beebe著 机械工业出版社
                  2. 《Linux shell的标准输入、输出和错误 》 http://blog.csdn.net/cjfeii/article/details/10084343

    共勉之

  • 相关阅读:
    go学习-环境安装1-WIN10如何安装wsl2
    go学习-环境安装2-wsl2安装docker
    go学习-使用swagger生成接口文档
    go学习-WSL安装gcc
    go学习-如何修改Docker0的IP地址的默认网段
    go学习-go-sqlmock数据库操作测试
    go学习-环境安装3-wsl安装golang
    java基础学习-Stream API
    go学习-gorm
    go学习-获取form表单提交数据
  • 原文地址:https://www.cnblogs.com/rond/p/3530843.html
Copyright © 2011-2022 走看看