Chinaunix首页 | 论坛 | 博客
  • 博客访问: 371260
  • 博文数量: 114
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1219
  • 用 户 组: 普通用户
  • 注册时间: 2015-02-07 21:23
文章分类

全部博文(114)

文章存档

2018年(1)

2017年(5)

2016年(87)

2015年(21)

我的朋友

分类: 系统运维

2016-07-07 16:43:39

数据流重导向
数据流重导向 (redirect) 就是将某个指令执行后应该要出现在屏幕上的数据, 给他传输到其它的地方



  1. 我们执行一个指令的时候,这个指令可能会由档案读入资料,经过处理之后,再将数据输出到屏幕上。 在
  2. 上图当中, standard output 与 standard error 分别代表标准输出与标准错误输出, 这两个玩意儿预
  3. 设都是输出到屏幕上面来的啊!举个简单例子来说, 我们下达『 cat /etc/crontab /etc/vbirdsay 』这
  4. 个指令时,cat 会由 /etc/crontab 与 /etc/vbirdsay 读入数据, 然后再将数据输出到屏幕上,不过,
  5. 因为系统本来就不存在 /etc/vbirdsay 这个档案, 所以就会显示错误讯息,这个错误讯息也会输出到屏
  6. 幕上来;
  7. 在这样的过程当中,我们可以将 standard error (简称 stderr) 与 standard output (简称 stdout) 给
    他传送到其它不同的地方,而不是屏幕上头!传送的目标处,通常是档案或者是装置! 而传送的指令则是
    如下所示:
    1. 标准输入(stdin) :代码为 0 ,使用 < 或 << ;
    2. 标准输出(stdout):代码为 1 ,使用 > 或 >> ;
    3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ;
    举例来说,如果我想要将我目前根目录下所有的目录都记录下来的话,也就是说,将 ls -l / 这个指令的
    输出结果储存下来,就可以:
    [root@linux ~]# ls -l / > ~/rootfile
    # 本来 ls -l / 会将根目录的数据列出到屏幕上;
    # 现在我使用了 > ~/rootfile 后,则本来应该在屏幕上出现的数据
    # 就会被『重新导向』到 ~/rootfile 档案内了!就可以将该数据储存!
    该档案的建立方式是:
    1. 该档案 (本例中是 ~/rootfile) 若不存在,系统会自动的将他建立起来,但是,
    2. 当这个档案存在的时候,那么系统就会先将这个档案内容清空,然后再将数据写入!
    3. 也就是若以 > 输出到一个既存盘案中,呵呵,那个档案就会被覆盖掉啰!
    那如果我想要将数据累加,不想要将旧的数据删除,那该如何是好? 呵呵!就利用 >> 就好啦!例如上面
    的例子中,就变成『ls -l / >> ~/rootfile』 如此一来,当 ~/rootfile 不存在时,系统会主动建立这
    个档案,若该档案已存在, 则数据会在该档案的最下方累加进去!基本上,指令的下达方式:


  8. 一串指令的最左边一定是指令,而在 >,2>,< 右边的,必须是档案或装置才行! 此外,那个 > 会
    等于 1> ,因为 standard output 代码是 1 ,可以省略啦! 再者, 1 与 > 之间并没有空格喔!是紧接
    在一起的!注意注意!我们底下来玩几个东西好了:
  9. 范例一:将目前目录下的档案信息全部储存到 list.txt 档案中
    [root@linux ~]# ls -al > list.txt
    范例二:将根目录下的数据也储存到 list.txt 档案中
    [root@linux ~]# ls -al / >> list.txt

    好了,对于『 > , >> 』这两个东西有一定的概念之后,我们来深入的谈一谈『数据流重导向』的观念吧!
    如前所述,基本上, Linux 执行的结果中,可以约略的分成『正确输出』与『错误输出』两种数据。 例
    如,当你以一般身份执行 find 这个指令时,例如执行『 find / -name testing 』时,由于你是一般身
    份,又有些数据夹是不允许一般身份者进入的, 所以啰,当你使用 find 时,就会有错误讯息发生了!但
    同时如果有 testing 这个档案在你可以进入的资料夹当中,那么屏幕也会输出到给你看!因此, 就具有
    正确的与错误的输出两种啰!(分别称为 Stdout 与 Stderror)例如下面为执行结果: 里面的『 find:
    /home/root: Permission denied 』就告诉你该数据夹你没有权限进入, 这就是错误的输出了,那么
    『 /home/dmtsai/tseting 』就是正确的输出了!
    [dmtsai@linux ~]$ find /home -name testing
    find: /home/test1: Permission denied <== Starndard error
    find: /home/root: Permission denied <== Starndard error
    find: /home/masda: Permission denied <== Starndard error
    /home/dmtsai/testing <== Starndard output
    好了,那么假如我们想要将数据输出到 list 这个档案中呢?执行『 find / -name testing > list 』 会
    有什么结果?呵呵,你会发现 list 里面存了刚刚那个『正确』的输出数据, 至于屏幕上还是会有错误的
    讯息出现呢!伤脑筋!如果想要将正确的与错误的数据分别存入不同的档案中需要怎么做?! 呵呵!其实
    在数据的重导向方面,正确的写法应该是『 1> 』与『 2> 』才对!但是如果只有 > 则预设是以 1> 来进
    行数据的!那个 1> 是输出正确数据, 2> 则是错误数据输出项目。也就是说:
    1  1> :是将正确的数据输出到指定的地方去
    2  2> :是将错误的数据输出到指定的地方去
    好了,那么上面的例子中,我们如何将数据输出到不同的地方去呢?可以这么写:
    [dmtsai@linux ~]$ find /home -name testing > list_right 2> list_error
    这样一来,刚刚执行的结果中,有 Permission 的那几行错误信息都会跑到 list_error 这个档案中,至
    于正确的输出数据则会存到 list_right 这个档案中啰!这样可以了解了吗? 如果有点混乱的话,去休息
    一下再来看看吧!!
    再来,如果我只要正确的数据,错误的信息我不要了呢?呵呵,这个时候 /dev/null 这个垃圾桶就很重要
    了!/dev/null 是什么呢? 基本上,那就有点像是一个『黑洞』的垃圾桶功能!当你输入的任何东西导向
    到这个虚拟的垃圾桶装置时, 『他就会凭空消失不见了~~』,这个东西有用的很!例如上面的例子中,
    我们可以这么做,来将错误的信息丢掉!
    [dmtsai@linux ~]$ find /home -name testing > list_right 2> /dev/null
    很神奇呦! error message 就会『不见了!』呵呵!真高兴!另外, 如果我要将数据都写到同一个档案
    中呢?这个时候写法需要用到特殊写法,请注意底下的写法呦!
    [dmtsai@linux ~]$ find /home -name testing > list 2> list <==错误写法
    [dmtsai@linux ~]$ find /home -name testing > list 2>&1 <==正确写法
    请特别留意这一点呢!同时写入同一个档案需要使用 2>&1 才对呦!
    OK!了解了 >, 2>, >> 与 /dev/null 之后,那么那个 < 又是什么呀!?呵呵!以最简单的说法来说, 那
    就是『将原本需要由键盘输入的数据,经由档案来读入』的意思。 举例来说,我们可以使用 cat 在键盘
    上面输入一些数据,然后写入一个档案内,例如:
    [root@linux ~]# cat > catfile
    testing
    cat file test
    <==这里按下 [ctrl]+d 结束输入来离开!
    此时就会有 catfile 这个档案产生,而且该档案的内容就是刚刚输入的内容喔。 那么,我是否可以使用
    其它档案来取代键盘输入呢?可以啊!这样做!
    [root@linux ~]# cat > catfile < somefile
    我可以先编辑 somefile ,然后再以上述的指令来将数据输出到 catfile 去呢!这样可以理解了吗? 能
    够理解 < 之后,再来则是怪可怕一把的 << 这个连续两个小于的符号了~ 他代表的是『结束的输入字符』
    的意思!举例来讲:『我要用 cat 直接将输入的讯息输出到 catfile 中, 且当输入 eof 时,该次输入
    就结束』,那我可以这样做:
    [root@linux ~]# cat > catfile < > This is a test testing
    > OK now stop
    > eof <==输入这个玩意儿,嘿!立刻就结束了!
    看到了吗?利用 << 右侧的控制字符,我们可以终止一次输入, 而不必输入 [crtl]+d 来结束哩!这对程
    序写作很有帮助喔!好了,那么为何要使用命令输出重导向呢? 这个问题一定会困扰你一下下的,如果你
    从来都没有写过 script 的话!好了,我们来说一说吧!
    1  当屏幕输出的信息很重要,而且我们需要将他存下来的时候;
    2  背景执行中的程序,不希望他干扰屏幕正常的输出结果时;
    3  一些系统的例行命令(例如写在 /etc/crontab 中的档案)的执行结果,希望他可以存下来时;
    4  一些执行命令,我们已经知道他可能的错误讯息,所以想以『 2> /dev/null 』将他丢掉时;
    5  错误讯息与正确讯息需要分别输出时。
    当然还有很多很多的功能的,最简单的就是网友们常常问到的: 『 为何我的 root 都会收到系统 crontab
    寄来的错误讯息呢』这个咚咚是常见的错误, 而如果我们已经知道这个错误讯息是可以忽略的时候,嗯!
    『 2> errorfile 』这个功能就很重要了吧! 了解了吗??

  10. 关于减号 - 的用途

    管线命令在 bash 的连续的处理程序中是相当重要的!另外,在 log file 的分析当中也是相当重要的一环, 所以请特别留意!另外,在管线命令当中,常常会使用到前一个命令的 stdout 作为这次的 stdin , 某些命令需要用到文件名 (例如 tar) 来进行处理时,该 stdin 与 stdout 可以利用减号 "-" 来替代, 举例来说:

    [root@www ~]# tar -cvf - /home | tar -xvf -

    上面这个例子是说:『我将 /home 里面的文件给他打包,但打包的数据不是纪录到文件,而是传送到 stdout; 经过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf - 』。后面的这个 - 则是取用前一个命令的 stdout, 因此,我们就不需要使用 file 了!这是很常见的例子喔!注意注意!




阅读(686) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~