返回列表 回复 发帖

> >> < << 2> 2>>

简单的说,标准输出指的是『命令运行所回传的正确的信息』,而标准错误输出可理解为『                命令运行失败后,所回传的错误信息』。举个简单例子来说,我们的系统默认有 /etc/crontab 但却无 /etc/vbirdsay,                此时若下达『 cat /etc/crontab /etc/vbirdsay 』这个命令时,cat 会进行:
               
  • 标准输出:读取 /etc/crontab 后,将该文件内容显示到屏幕上;
  • 标准错误输出:因为无法找到 /etc/vbirdsay,因此在屏幕上显示错误信息
                不管正确或错误的数据都是默认输出到屏幕上,所以屏幕当然是乱乱的!那能不能透过某些机制将这两股数据分开呢?                当然可以啊!那就是数据流重导向的功能啊!数据流重导向可以将 standard output (简称 stdout) 与 standard error                output (简称 stderr) 分别传送到其他的文件或装置去,而分别传送所用的特殊字符则如下所示:
               
  • 标准输入  (stdin) :代码为 0 ,使用 < 或 << ;
  • 标准输出  (stdout):代码为 1 ,使用 > 或 >> ;
  • 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ;
                为了理解 stdout 与 stderr ,我们先来进行一个范例的练习:
范例一:观察你的系统根目录 (/) 下各目录的文件名、权限与属性,并记录下来[root@www ~]# ll /  <==此时屏幕会显示出文件名信息[root@www ~]# ll / > ~/rootfile <==屏幕并无任何信息[root@www ~]# ll  ~/rootfile <==有个新档被创建了!-rw-r--r-- 1 root root 1089 Feb  6 17:00 /root/rootfile
                怪了!屏幕怎么会完全没有数据呢?这是因为原本『 ll / 』所显示的数据已经被重新导向到 ~/rootfile 文件中了!                那个 ~/rootfile 的档名可以随便你取。如果你下达『 cat ~/rootfile 』那就可以看到原本应该在屏幕上面的数据啰。                如果我再次下达:『 ll /home > ~/rootfile 』后,那个 ~/rootfile 文件的内容变成什么?                他将变成『仅有 ll /home 的数据』而已!咦!原本的『 ll / 』数据就不见了吗?是的!因为该文件的创建方式是:
               
  • 该文件 (本例中是 ~/rootfile) 若不存在,系统会自动的将他创建起来,但是
  • 当这个文件存在的时候,那么系统就会先将这个文件内容清空,然后再将数据写入!
  • 也就是若以 > 输出到一个已存在的文件中,那个文件就会被覆盖掉啰!
                那如果我想要将数据累加而不想要将旧的数据删除,那该如何是好?利用两个大于的符号 (>>)                就好啦!以上面的范例来说,你应该要改成『 ll / >> ~/rootfile 』即可。                如此一来,当 (1) ~/rootfile 不存在时系统会主动创建这个文件;(2)若该文件已存在,                则数据会在该文件的最下方累加进去!
                上面谈到的是 standard output 的正确数据,那如果是 standard error output 的错误数据呢?那就透过 2> 及                2>> 啰!同样是覆盖 (2>) 与累加 (2>>) 的特性!我们在刚刚才谈到 stdout 代码是 1 而 stderr 代码是 2 ,                所以这个 2> 是很容易理解的,而如果仅存在 > 时,则代表默认的代码 1 啰!也就是说:
               
  • 1> :以覆盖的方法将『正确的数据』输出到指定的文件或装置上;
  • 1>>:以累加的方法将『正确的数据』输出到指定的文件或装置上;
  • 2> :以覆盖的方法将『错误的数据』输出到指定的文件或装置上;
  • 2>>:以累加的方法将『错误的数据』输出到指定的文件或装置上;
                要注意喔,『 1>> 』以及『 2>> 』中间是没有空格的!OK!有些概念之后让我们继续聊一聊这家伙怎么应用吧!                当你以一般身份运行 find                这个命令的时候,由于权限的问题可能会产生一些错误信息。例如运行『 find / -name                 testing 』时,可能会产生类似『 find: /root: Permission denied 』之类的信息。                例如底下这个范例:
范例二:利用一般身份账号搜寻 /home 底下是否有名为 .bashrc 的文件存在[root@www ~]# su - dmtsai  <==假设我的系统有名为 dmtsai 的账号[dmtsai@www ~]$ find /home -name .bashrc <==身份是 dmtsai 喔!find: /home/lost+found: Permission denied  <== Standard errorfind: /home/alex: Permission denied        <== Standard errorfind: /home/arod: Permission denied        <== Standard error/home/dmtsai/.bashrc                       <== Standard output
                由于 /home 底下还有我们之前创建的账号存在,那些账号的家目录你当然不能进入啊!所以就会有错误及正确数据了。                好了,那么假如我想要将数据输出到 list 这个文件中呢?运行『 find /home -name .bashrc > list 』                会有什么结果?呵呵,你会发现 list 里面存了刚刚那个『正确』的输出数据,                至于屏幕上还是会有错误的信息出现呢!伤脑筋!如果想要将正确的与错误的数据分别存入不同的文件中需要怎么做?
范例三:承范例二,将 stdout 与 stderr 分存到不同的文件去[dmtsai@www ~]$ find /home -name .bashrc > list_right 2> list_error
                注意喔,此时『屏幕上不会出现任何信息』!因为刚刚运行的结果中,有 Permission 的那几行错误信息都会跑到 list_error                 这个文件中,至于正确的输出数据则会存到 list_right 这个文件中啰!这样可以了解了吗?                如果有点混乱的话,去休息一下再来看看吧!


               
  • /dev/null 垃圾桶黑洞装置与特殊写法
                想象一下,如果我知道错误信息会发生,所以要将错误信息忽略掉而不显示或储存呢?                这个时候黑洞装置 /dev/null 就很重要了!这个 /dev/null 可以吃掉任何导向这个装置的信息喔!将上述的范例修订一下:
范例四:承范例三,将错误的数据丢弃,屏幕上显示正确的数据[dmtsai@www ~]$ find /home -name .bashrc 2> /dev/null/home/dmtsai/.bashrc  <==只有 stdout 会显示到屏幕上, stderr 被丢弃了
                再想象一下,如果我要将正确与错误数据通通写入同一个文件去呢?这个时候就得要使用特殊的写法了!                我们同样用底下的案例来说明:
范例五:将命令的数据全部写入名为 list 的文件中[dmtsai@www ~]$ find /home -name .bashrc > list 2> list  <==错误[dmtsai@www ~]$ find /home -name .bashrc > list 2>&1     <==正确[dmtsai@www ~]$ find /home -name .bashrc &> list         <==正确
                上述表格第一行错误的原因是,由于两股数据同时写入一个文件,又没有使用特殊的语法,                此时两股数据可能会交叉写入该文件内,造成次序的错乱。所以虽然最终 list                 文件还是会产生,但是里面的数据排列就会怪怪的,而不是原本屏幕上的输出排序。                至于写入同一个文件的特殊语法如上表所示,你可以使用 2>&1 也可以使用 &> !                一般来说,鸟哥比较习惯使用 2>&1 的语法啦!
返回列表