数据流重导向
数据流重导向 (redirect) 就是将某个指令执行后应该要出现在屏幕上的数据, 给他传输到其它的地方
-
我们执行一个指令的时候,这个指令可能会由档案读入资料,经过处理之后,再将数据输出到屏幕上。 在
-
上图当中, standard output 与 standard error 分别代表标准输出与标准错误输出, 这两个玩意儿预
-
设都是输出到屏幕上面来的啊!举个简单例子来说, 我们下达『 cat /etc/crontab /etc/vbirdsay 』这
-
个指令时,cat 会由 /etc/crontab 与 /etc/vbirdsay 读入数据, 然后再将数据输出到屏幕上,不过,
-
因为系统本来就不存在 /etc/vbirdsay 这个档案, 所以就会显示错误讯息,这个错误讯息也会输出到屏
-
幕上来;
-
在这样的过程当中,我们可以将 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 不存在时,系统会主动建立这
个档案,若该档案已存在, 则数据会在该档案的最下方累加进去!基本上,指令的下达方式:
-
一串指令的最左边一定是指令,而在 >,2>,< 右边的,必须是档案或装置才行! 此外,那个 > 会
等于 1> ,因为 standard output 代码是 1 ,可以省略啦! 再者, 1 与 > 之间并没有空格喔!是紧接
在一起的!注意注意!我们底下来玩几个东西好了:
-
范例一:将目前目录下的档案信息全部储存到 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 』这个功能就很重要了吧! 了解了吗??
-
关于减号 - 的用途
管线命令在 bash 的连续的处理程序中是相当重要的!另外,在 log file 的分析当中也是相当重要的一环, 所以请特别留意!另外,在管线命令当中,常常会使用到前一个命令的 stdout 作为这次的 stdin , 某些命令需要用到文件名 (例如 tar) 来进行处理时,该 stdin 与 stdout 可以利用减号 "-" 来替代, 举例来说:
[root@www ~]# tar -cvf - /home | tar -xvf -
上面这个例子是说:『我将 /home 里面的文件给他打包,但打包的数据不是纪录到文件,而是传送到 stdout; 经过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf - 』。后面的这个 - 则是取用前一个命令的 stdout, 因此,我们就不需要使用 file 了!这是很常见的例子喔!注意注意!
-
阅读(722) | 评论(0) | 转发(0) |