【教程】普及讲解重定向
bat吧
全部回复
仅看楼主
level 14
【教程】普及讲解重定向
作者:bat吧-aiwozhonghuaba
系统环境:WindowsXP SP3
简介:
重定向是批处理非常重要的组成部分之一,从简单的>,>>,<到"罕见"的1>&2,1<&2,乃至于管道符号'|'都是属于重定向的范畴
但很多人对于重定向的了解还十分少,只停留在非常浅的层次
——知道>a.txt可以将命令执行结果发送到a.txt,但不知道'Echo 1 2 3>a.txt'为什么不能得到
正确的
结果
——知道>nul可以屏蔽输出,但不知道当命令执行错误时的输出该如何屏蔽
——知道2>nul可以屏蔽错误输出,但不知道为什么有时'>nul 2>nul'还是不能屏蔽所有输出
——知道管道符号可以传递前一个命令的执行结果,却不知道错误输出该如何传递
正所谓学无止境,笔者也曾以为以为批处理中应该没有什么是我不知道的了,后来看见了'Echo;>nul 3>a.txt'这样的代码,
一番百度之下才知道自己实在是自大了,原来看似简单的重定向中隐藏着如此多的秘密,在如饥似渴地阅读了大量相关教程与代码(如英雄和bathome的一些帖子,还有微软该死的机器翻译...)后,终于在这方面有所了解,故开此贴,为新手普及一下重定向的知识,让老手欣赏到一个不一样的重定向
最后,本人知识有限,如有错误或遗漏部分,还望指出
2015年01月18日 07点01分 1
level 14
基础知识1:标准I/O
通常我们执行一个命令,就会得到一个输出(大部分命令都是这样的)
命令执行成功的输出,被称作”标准输出(StdOut)”
命令执行失败的输出,被称作”标准错误输出(StdErr)”,这
有些命令会等待你输入一个值,我们称这为”标准输入(StdIn)”,比如Set /P,Comp,标准输入和标准输出合称”标准I/O”
值得一提的是,’Set /P Str=<Test.txt’这样的代码也用到了标准输入,只不过输入不是从键盘而是从直接文件获取
你也可以这样理解,
返回值(%ErrorLevel%)为0的时候,输出一般就是标准输出
返回值为其他的时候(一般情况下为1),输出一般就是标准错误输出
结合例子更形象
@Echo Off
Echo;Hello
Echo %ErrorLevel%&Echo;
EchoYes
Echo %ErrorLevel%&Echo;
Pause
2015年01月18日 07点01分 2
先顶一个!好帖
2015年03月03日 02点03分
(Echo 1 2 3)>a.txt不就行了
2016年06月12日 14点06分
level 12
学习了,,,
2015年01月18日 07点01分 3
level 14
基础知识2:设备
重定向符号后面一般都会接上设备,如’Echo;>nul’,这里的nul就是”空设备”
了解一下设备将会对后面的学习有一定的帮助
本教程只讨论前两个,后面的实在是不常用
NUL 大家最常用的一个设备,一般用于屏蔽输出,比如’Dir >nul’
CON 标准输入/输出设备,它代表了两个玩意儿,一是键盘(用于
标准输入),二是控制台(用于
标准输出),不过这里的标准输出是广义的,标准错误输出也被囊括其中
基础知识3:句柄
句柄也是重定向的基本组成部分之一
句柄总共有10个,代表了相应的输出
句柄1代表
标准输出,换个说法,
标准输出的结果被储存在句柄1中
对标准输出进行重定向,就是对句柄0中承载的数据进行重定向,这样的数据被称作数据流,句柄1中承载的数据流被称作"标准输出流"
句柄2同样,只不过要把标准输出换成
标准错误输出
3-9比较特殊,这里稍微了解一下以免出现这个概念时茫然即可,后面会再次提到的
需要注意的是,这里的句柄指的不是1012这样的Handle,不过微软说它叫句柄,那我们就叫它句柄吧
基础知识4:重定向的基本结构
("&"代表这两个字符串是连在一起的)
命令 句柄&符号&设备
如:Dir 1>dir.txt

句柄&符号&设备 命令
如:1>echo.txt Echo;Hello,batch~
这里推荐后面的写法,原因是
Echo 5>a.txt
[滑稽]猜一猜执行结果,再实际执行一次看看
2015年01月18日 07点01分 4
echo 5>a.txt。。。为什么
2015年01月25日 00点01分
回复
ħ�g������
:因为后面的5被当作句柄处理了
2015年01月25日 05点01分
@aiwozhonghuaba 3~9怎么自定义
2015年01月25日 08点01分
回复
ħ�g������
:发现个问题。。“echo 5>x.txt" 这样是句柄, ”echo 5 >x.txt" 这样是正常输出的.紧挨着符号的才是句柄,空一个格就不是了。[汗]
2015年01月25日 08点01分
level 11
嗯嗯,好东西
2015年01月18日 07点01分 5
level 14
第一讲:符号’>’和’>>’
> 将命令的执行结果重定向到设备或文件
>> 将命令的执行结果追加到文件末尾
基础知识1里的例子大家肯定都记得(不记得的请按’Home’)
那么问题来了,当我们需要把这些信息写入到其他地方去的时候,该怎么办呢?
笔者一般会这样做
>>a.txt Echo;Hello
2>nul EchoYes
此时命令的输出是这样的,只留下了返回值
这是原输出(不包括红字......)
那么本来该有的玩意儿们都到哪里去了呢?
实际上‘
Echo;Hello’的执行结果到了a.txt中,不过我懒得打开看了,各位无聊的话可以试一试

EchoYes’的执行结果呢,到了nul中,可是为什么找不到呢?还记得吗,nul是空设备,也就相当于一个不存在的设备,因此执行结果就这样消失了(利用NUL的这一点,我们常常用它来屏蔽输出)
当然,为了装13,你也可以用aux或com1来屏蔽输出,如果出现了副作用,请告诉我[滑稽]
这种将命令输出转移到其他设备的过程,就被称作重定向
这里的’>>’就是"
符号"了,大家都对它非常熟悉吧
现在们来分析一下代码
第一行代码,将Echo;Hello的标准输出重定向到了a.txt,可能有人会很疑惑,不是说重定向符号的使用格式是’句柄&符号&设备’吗怎么没看见句柄啊? 各位莫急,将回显打开试试?
看,句柄在这里![喷]隐藏地真深啊
CMD看我们没有指定句柄,就为自动它加上了1,并且将重定向移到了代码后方
(句柄1,是’>’和’>>’符号的默认句柄,因此’Dir >dir.txt’等价于’Dir 1>dir.txt’)
第二行代码,将’EchoYes’的标准输出重定向到了NUL(空设备),从而起到了屏蔽输出的效果果,不过如果你用>nul是起不到这样的效果的,为什么呢?
笑而不语,读者自己思考思考
(PS 句柄2,不是任何重定向符号的默认句柄)
你可以多次尝试运行上面的代码
然后你发现a.txt里有了一大堆Hello.........
这就是>>的效果——追加
如果把>>改成>呢?
自己试试吧
PS >>和>在使用时需要注意,>>还好,顶多出来了一个超大的txt...但>的使用一定要小心,不然万一往重要文件里写入了点什么......什么,你还不明白?你一定没有按我上面说的那样做一做
小技巧:
有大量命令的输出需要重定向可以这样
(
命令1
命令2
......
)>>Test.txt
代码很多时效率会显著提升
2015年01月18日 07点01分 6
副作用是不是设备没法用了[喷]
2015年01月31日 13点01分
回复
�ʼҴ�����
:[滑稽]这个真不知道
2015年02月01日 08点02分
[真棒]
2015年08月12日 00点08分
小技巧中>>test.txt可以替换成>test.txt
2015年08月12日 07点08分
level 14
第二讲:符号’<’
将标准输入重定向到别处
经典的用法
Set /P Str=<a.txt
从a.txt中获取第一行赋给Str(代替了原来的键盘)
PS 万一要获取很多行呢?(For /L %%i In (1 1 10) Do Set /P Str%%i=)<a.txt
我们再次将回显关闭,又发现了隐藏着的句柄,实在是猥琐啊
(句柄0,是”标准输入”的默认句柄,不过标准输入的符号其实就只有”<”)
那么Set /P Str=又是怎么回事,关掉回显后它也很正常啊
没错,它非常地正常,没有0,也没有’<’.这算是一种变相的默认吧(’Set /P Str=’等价于’Set /P Str=<con’)
还记得标准输入的设备吗?
键盘! 符号CON
如果我们将代码改成
Set /P Str=1<con呢,当然,非常和谐,和Set /P没有区别
改成
Set /P Str=2<con,依然很和谐……句柄被无视了
改成
Set /P Str=<nul呢,诶?怎么没等待我输入啊,此事定有蹊跷,让我加一些提示语看看
改成
Set /P Str=请输入一个数<nul
好像有点不对劲了是吗?
这是因为一般情况下,Set /P 等待我们输入时,我们输入完毕后键入回车时,实际上键入了一个
换行符”Chr(10)”和一个
回车符”Chr(13)”
(有些人看到这里就会恍然大悟,不就是\n和\r吗?)
而<nul,不是从键盘,而是从nul(空设备)中获取输入.但nul里面有内容吗?没有,那怎么办,一直呆在那里?
当然不是,此时nul给了Set /P一个回车符,得到了返回,Set /P屁颠屁颠地结束了,但是换行符呢?没有!
因此下一行输出会出现到同一行上面,也就是所谓的”续行”
把nul换成其它的,也都是同样的效果
换成a.txt
继续
改成
Set /P Str=请输入一个数 1<a.txt
Oops,怎么没有提示语?怎么需要等待我输入?
改成
Set /P Str=请输入一个数 2<a.txt
提示语回来了,不过仍然需要等待一个输入
看起来,从文件中获取输入必须使用"标准输入句柄"
但为什么改成其他的就要等待输入了呢?
这个问题留给读者去探究了[滑稽][冷][喷]
(需要注意的是,这个续行区别于^,前者是在命令行窗口里续行,后者是通过转义换行符在代码中续行)
2015年01月18日 08点01分 8
Set /P Str=请输入一个数 0<a.txt
2016年06月12日 14点06分
Oooooooooooooops,your files are encrypted[滑稽]
2017年06月30日 14点06分
获取很多行:(For /L %%i In (1 1 10) Do Set /P Str%%i=)<a.txt 这句是不写错了啊?
2018年05月30日 09点05分
level 14
一开始不应该搞太难的东西
2015年01月18日 09点01分 10
这只是单个命令的教程,必然要全面
2015年01月18日 09点01分
好吧
2015年01月18日 09点01分
加括号秒杀一切(Rd $Test 2>&1)|Findstr “目录不是空的”
2016年06月12日 14点06分
level 14
第四讲:符号’<&’和’>&’
它们的作用相同
将后面的句柄的指向复制给前面的句柄
在这里我就仁慈地把也许杀死了你们许多脑细胞的问题来解决吧
还记得第二讲的
Set /P Str=请输入一个数 2<a.txt
吗?
你们先思考一下这个问题
我顺便把另一个个问题解决,权当是给你们一点提示
Set /P Str=2<con
为什么还会等待输入呢?
首先,CMD把句柄2重定向到con
然后呢,CMD发现句柄0没有被重定向,于是它照常执行,句柄0默认是从con中获取输入的
因此就相当于
Set /P Str=0<con 2<con
你们思考完了吗?
答案其实在上面已经写出来了
我们只是修改了句柄2的指向,句柄0的指向没有变
因此上面的代码相当于
Set /P Str=请输入一个数 0<con 2<a.txt
那么该怎么解决呢...你可以这样
Set /P Str=请输入一个数 2<a.txt 0>&2
[喷]这是什么奇怪的用法?
这就是传说中的句柄复制了
简要描述一下这个过程
1.2<a.txt 2的指向被重定向为a.txt
2.0>&2 后面句柄的指向复制给前面一个句柄,也就是句柄2的指向被复制给了句柄0
3.此时,句柄2指向a.txt,句柄0也指向a.txt
4.Set /P从句柄0中读取数据,也就是读取a.txt中的数据,直到咯嘣遇到了回车符,结束~
有没有指针的既视感[滑稽]
再来几个
More 2>a.txt 0>&2
Echo;Batch 5>b.txt 4<&5 8>&4 1<&8
第一个
1.句柄2的指向被重定向为a.txt
2.句柄0的指向被重定向为句柄2的指向
3.此时2指向a.txt 0指向a.txt
4.More从句柄0中读取数据
第二个
1.句柄5的指向被重定向为b.txt
2.句柄4的指向被重定向为句柄5的指向,即b.txt
3.句柄8的指向被重定向为句柄4的指向,即b.txt
4.句柄1的指向被重定向为句柄8的指向,即b.txt
5.执行Echo;Batch,成功!结果被写入到标准输出
6.标准输出流被重定向到b.txt
2015年01月18日 10点01分 11
level 14
看到这里的读者,非常地有恒心
让我们小小地总结一下
==========分隔符==========
==========分隔符==========
每条语句后面其实都跟着
0<con 1>con 2>con
以下部分为选修,你真的打算看下去?
其实我应该用这幅图来
镇楼
,狂拽酷炫吊炸天
2015年01月18日 11点01分 12
既然不是坟又看到这里了于是顺便顶一下。
2015年01月28日 20点01分
level 12
[真棒]这么好的贴子没人顶?
2015年01月18日 11点01分 13
[乖]谢谢支持
2015年01月18日 12点01分
我想说……其实可以(call 文件名)>nul 2>&1
2016年06月12日 14点06分
还可以(数行内容)>nul 2>&1
2016年06月12日 14点06分
@幻虚道长🍭 其实,这是个坟贴
2016年06月13日 10点06分
level 15
太长,先留名
2015年01月18日 12点01分 15
level 14
基本写成,不过太晚了不调试了
2015年01月18日 15点01分 16
大神终于出教材了,已收藏,恭候大神继续更新……
2015年01月19日 12点01分
level 10
[haha][乖] 特么看不懂
2015年01月19日 08点01分 17
level 12
顶!
2015年01月19日 10点01分 18
level 14
自顶
@超人硬汉 虽然未更完,但还是可耻地求精了
2015年01月20日 14点01分 19
for /l %%i in (1 1 32) do md %%i赞
2015年01月21日 03点01分
回复
����1heaven
:谢谢支持
2015年01月21日 14点01分
level 15
于是你就被加精了
2015年01月21日 12点01分 20
[太开心]
2015年01月21日 14点01分
level 12
看完楼主的帖子真是受益匪浅,给楼主32个赞!
2015年01月24日 12点01分 21
那真是极好
2015年01月24日 12点01分
[开心]啊byaidu
2015年03月02日 09点03分
level 13
大神的教程怎能不学习?
——另,潜水已久,想回来回个帖,发现每层楼的【回复】按钮都不见了= =,简直无解......
2015年01月24日 12点01分 22
[乖]皇叔欸!——您一定是读多数近视了......
2015年01月24日 13点01分
@aiwozhonghuaba 电脑的问题…手机还是看得到……
2015年01月24日 16点01分
@黄田杰 确信看得到
2016年06月12日 14点06分
level 9
原来我就是个普通新手。[泪]
2015年01月25日 01点01分 23
1 2 3 尾页