重定向符号主要有:>,>>,<,>&,<&和|,而本文只讨论前五个。

第一节

首先从一个经典问题开始,“1>nul 2>nul”的意思是既屏蔽正常的输出又屏蔽错误的输出,那么我们马上就知道了这里的1代表正常输出(即所谓的“标准输出”–stdout),2代表错误输出(即所谓的“标准错误输出”–stderr)。

1和2其实是句柄stdout和stderr的数字代号,至于什么是句柄,我认为可以理解为某种事物的一种标识,或者说这个句柄指向某个事物。举个例子来说,“标准输出”以句柄stdout为标识,或者说句柄stdout指向“标准输出”。

还有一个句柄–stdin,它是所谓“标准输入”的标识,数字代号是0。除此之外还有3~9可用,只是它们没有定义。

“标准输出”和“标准错误输出”默认是要输出到控制台con(即cmd窗口)的,而“标准输入”默认是由控制台con(即键盘)输入的,因此重定向的目的就是将输入输出流从默认位置重定向到新的位置。符号“>”和“>>”的默认句柄代号是1,而“<”的默认句柄代号是0。

“echo hhhhhh”类似于这样的语句可以说是我们再熟悉不过的了,但这只是种默认的状态,其实里面还有一些内容。这一句完整的应该是这样的:“echo hhhhhh 1>con 2>con”,意思是将echo命令的结果中的标准输出和标准错误输出输出到控制台con中,只不过此时标准错误输出是空的。

再看一个例子,如果给dir一个错误的参数,例如“dir /mm”,那么写全了就是“dir /mm 1>con 2>con”,只不过此时的标准输出是空的。如果你这样写的话“dir /mm 1>hero.txt”,那么屏幕上会照常显示错误信息但hero.txt中不会有内容。

再来一个标准输入的例子,“set /p var= ”其实应该是这样的“set /p var= 0<con”,只是因为0<con是默认值可以省略。我们当然可以从文件中读取输入,如“set /p var= 0<file.txt”,0是默认值可以省略。

nul代表的是“空设备”,是一个不存在的设备,将输出流重定向到空设备就相当于屏蔽掉了一样。而如果从空设备中读取输入,自然是读不到东西的,但的确是输入了,这也就是“set /p var=<nul”中“<nul”相当于回车但不换行的原因。

将正常异常输出到同一文件,dir file.c 1> output.msg 2>&1  用“2>&1”将标准错误输出重定向到标准输出。

第二节

好了,说到这里,相信大家对重定向输出和输入又有了进一步的了解,关于重定向输出到文件和由文件重定向输入的问题在此也不再复述。我下面要讲的是句柄代码之间的“重定向”。

之前不是提到过还有3~9这7个句柄数字代号吗,这些究竟有什么用?说实话,基本没什么用,因此建议你如果不是迫切想知道这部分内容的话就不要往下看了。

“echo hero 1>hero.txt”这一句是将标准输出重定向到文件hero.txt,相当于将句柄代号1的指向由con变为hero.txt。“echo hero 3>hero.txt 1<&3”,这句的结果是生成了文件hero.txt,其内容为hero,过程是这样的:“3>hero.txt”是将句柄数字代号 3的指向由“空”变为hero.txt;“1<&3”是将句柄数字代号3的指向复制给1的指向,此时1的指向就为hero.txt了,因此标准输出就被重定向到hero.txt中了。

“i<&j”和“i>&j”的效果都是把j的指向复制给i。“echo hero >hero.txt 2>&1”这句的意思是,无论是标准输出还是标准错误输出都会被重定向到hero.txt中,具体过程:1的指向由con转为 hero.txt,“2>&1”是把1的指向复制给2,此时2的指向也变为了hero.txt,因此1和2都会被重定向到hero.txt 中。注意:1是符号“>”的默认句柄数字代号。

再看“echo hero 3>hero.txt”,这个为什么就不能将结果重定向到文件中呢?记住,我们要重定向的只有标准输入、标准输出和标准错误输出,因此真正“干活” 的就只有0、1和2,因为它们分别指代了前面的三者,而3没有指代任何句柄只能作为间接量使用。

“more 3<hero.txt 0>&3”这句是显示文件hero.txt,具体过程:“3<hero.txt”把3的指向变为 hero.txt,“0>&3”把3的指向复制给0,即0指向了hero.txt(只不过这次是从hero.txt中读取数据)。强调一下,真正能读取数据的是0而不是3,3只是作为中间量而已。刚才这句我们当然可以这么写:“more 0<hero.txt”或直接“more <hero.txt”。

再来一个例子“echo hero 5>hero.txt 4>&5 3<&4 1<&3”,结果输出到了hero.txt中。具体过程:5的指向变成hero.txt,“4>&5”把5的指向复制给 4,“3>&4”把4的指向复制给3,“1>&3”把3的指向复制给1,最终1的指向就是hero.txt,则1所指代的标准输出就被重定向到了hero.txt。

第三节

注意:这一节的内容都是围绕着下面这个例子进行叙述的。
代码:
@echo off
echo 英雄是好男人!!!
echo. 1>nul 3>nul
echo 英雄是
echo 英雄是
echo 这是怎么回事,难道就不能 1>con 4>con
pause
这究竟是怎么回事?为什么结果会如此出乎意料?

这里涉及到一个所谓“备份”的问题,就是在修改某个句柄代号的指向之前,系统会把该句柄代号原来的指向备份到截止到目前第一个指向为空的句柄代号中。目的是当这一行的程序结束之后,系统可以通过备份找回原来的指向。

在继续阅读之前建议你准备好纸笔,以便能记录下各个代号指向的变化,这样不至于混乱。

我们现在把焦点集中到这句“echo. 1>nul 3>nul”上来。这句究竟是如何工作的呢?

第一步:在运行“1>nul”之前,1的指向是默认值con,此时代号3~9的指向都是空(初始值),因此系统会把1的指向备份到3(因为3是第一个为空的代号),3就指向了con。就是说系统把1原来的指向复制给了3,目的是语句结束后能找回原来的指向,这就相当于备份。

第二步:现在3的指向是con。然而由于要运行“3>nul”,因此还要备份3的指向。此时4是空的,系统就把3的指向con复制给了4,即4现在指向con。就是说3以4为备份。

第三步:由于“3>nul”使得3指向了nul。

第四步:这行语句结束时,1要找回原来的指向,从以上叙述我们知道,3是1的备份,因此1要通过3来恢复“原来”的指向,但此时3的指向已经变为了nul,故1就指向nul。

第五步:而3要恢复原来的指向就要找4,4指向con,故3恢复为con;4原始指向是空的,其备份在5中,故4的指向恢复到空。

至此我们理顺一下,现在1指向nul,2指向默认值con,3指向con,4之后都是空指向。那么在运行后两句echo语句时由于1指向nul,即标准输出被重定向到空设备,故显示被屏蔽。

再来看看这句 “echo 这是怎么回事,难道就不能骂骂英雄吗??? 1>con 4>con” 这句是怎么工作的呢?

第一步:1当前指向是nul,由于要运行“1>con”,因此要进行备份。但此时3指向的是con非空,故系统将1的指向备份到4,即4指向nul。

第二步:又由于要运行“4>con”,故4现在的指向nul就又被备份到5中,5以后的事姑且省略。

第三步:运行完“4>con”之后4就指向con。

第四步:该行程序结束后,1要通过4来恢复指向。4指向con,故1指向con从而恢复了默认状态。而4找5,5指向nul,故4指向nul。

我们再数一数现在的情况,0指向con,1指向con,2指向con,3没动还是指向con,4指向nul,5以后都为空指向。

会不会有点乱?那就再好好的看几遍吧,我也实在没有什么好办法了。

第四节

我们已经知道“echo hero”相当于“echo hero 1>con 2>con”,con代表了控制台,可以把con看做是特殊的文件,这就是我们无法建立名为con文件的原因。

再对“>”和“>>”的重定向机制做个分析。当要重定向到的文件有隐藏或系统属性时,“>>”可以正常运行,而 “>”就无法操作了。据此我推测,对于“>”的重定向输出,如果文件不存在当然是建立文件,而如果文件存在就先将文件删除,然后再新建文件,也就是说并非是覆盖文件的内容而是先删除文件再建立新文件。
 
    通过第三节的讲解你应该明白为什么类似这样的语句“echo hero >nul >con >hero.txt >con”会以最后一个为准了吧。

最后需要注意一点的是–重定向输出无法输出到只读文件。

bat输出重定向的更多相关文章

  1. linux进程后台运行及输出重定向

    本机环境为ubuntu 14.04 以ping www.baidu.com为例: 1.程序的前台运行 ping www.baidu.com 可以看到,屏幕上输出了baidu返回的结果 2.实现程序后台 ...

  2. unix下输出重定向

    > 为重定向符号 >> 重定向不覆盖原文件内容 example: 1. 标准输出重定向 echo "123" > /home/123.txt ---- 标准 ...

  3. [转]linux shell数据重定向(输入重定向与输出重定向)详细分析

      在了解重定向之前,我们先来看看linux 的文件描述符. linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件 ...

  4. linux | 管道符、输出重定向

    1 输出重定向 ll > a.txt 将 ll的结果写入到a.txt 2 管道符 ls -la | grep h* 这条命令的理解为:ls -la 的结果作为gerp h* 的结果 gerp 是 ...

  5. python输出重定向

    0表示标准输入1表示标准输出2表示标准错误输出> 默认为标准输出重定向,与 1> 相同2>&1 意思是把 标准错误输出 重定向到 标准输出.&>file 意思是 ...

  6. 学习笔记之Shell脚本的输出重定向

    shell http://baike.baidu.com/link?url=qN3THt5ZJhQtwRJJkakWdz5-vZp4V9H3OmNP97XNhaoL-dqU-6rrFrYfHXmYv6 ...

  7. Linux实时将所有输出重定向到文件

    Linux的重定向机制十分好用,我们经常需要在服务器上挂起一个服务程序,然后将该程序的所有输出重定向到某个文件,这样即使我们注销了用户,程序依然在linux服务器上运行着. 但是重定向的输出经常无法实 ...

  8. 禁止输出重定向(>)覆盖已存在文件(防止误操作)

    在输出重定向中,>表示重定向并覆盖已有文件内容,为了防止误操作,覆盖重要的内容,可以使用如下命令: set -C 这样输出重定向到一个已有文件就会提示: cannot overwrite exi ...

  9. Shell 输入/输出重定向

    大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端.命令通常从标准输入的地方读取输入,默认是终端.标准输出,默认情况下是终端. 重定向命令列表如下: 命令 说明 comm ...

随机推荐

  1. 浅谈对NaN的理解

    1.NaN : Not a Number 不是一个数字 2.NaN 与其他数值进行比较的结果总是不相等的,包括它自身在内 3.判断是否是NaN, 方法一  :is.NaN(变量): 方法二   :Nu ...

  2. JavaSE——线程调度

    线程调度: 按照特定机制为线程分配cpu的使用权. 线程调度模型: 分时调度 所有线程轮流获得cpu的使用权,平均分配每个线程占用的cpu的时间片. 抢占时调度(java虚拟机) 可运行池中优先级高的 ...

  3. Java学习笔记之异常处理

    一.异常的分类 1.由Java虚拟机抛出的异常(Error):程序无法处理的问题,用户不用去进行处理(虚拟机错误丶内存溢出错误丶线程死锁) 2.Exception异常:程序本身可以进行处理的异常 1. ...

  4. css设计并排布局

    css code form#reset_password ul { list-style: none; margin: 0 0 20px 200px; padding:; } form#reset_p ...

  5. 前端需要掌握的后台基础:HTTP协议

    什么是HTTP? 以下来自度娘最为专业的解释: 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标 ...

  6. Oracle EBS INV 创建物料搬运单头

    CREATE OR REPLACE PROCEDURE XX_CreateMoveOrderHeader AS -- Common Declarations l_api_version NUMBER ...

  7. linux操作系统不重启添加raid0步骤

    1.限制:本步骤仅适用于LSI芯片的raid卡,可以通过以下蓝色指令判断是否LSI芯片 [root@HKC-Lab-CDN ~]# lspci | grep -i lsi 03:00.0 RAID b ...

  8. python之demo1----改编自turtle.py文件中的demo

    """ 改编自turtle.py自带demo 执行 python -m turtledemo 命令查看系统内置demo的源码 绘制:需要通过import turtle引入 ...

  9. MySQL客户端连接方式

    MySQL连接方式MySQL除了最常见的TCP连接方式外,还提供SOCKET(LINUX默认连接方式).PIPE和SHARED MEMORY连接方式.各连接方式的服务器.客户端启动选项,及连接默认值见 ...

  10. OpenGL超级宝典笔记——贝塞尔曲线和曲面(转)

    http://my.oschina.net/sweetdark/blog/183721 参数方程表现形式 在中学的时候,我们都学习过直线的参数方程:y = kx + b;其中k表示斜率,b表示截距(即 ...