[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[分享]再谈神奇的批处理句柄备份

大家先猜猜运行下面这段代码会出现什么样的结果,然后我们再来谈谈为什么会出现这种结果。
  1. @echo off 2>&3 3>nul&@1>&4 4>nul
  2. echo 表演开始罗 :>con
  3. echo 看见我了吗?
  4. set /a a=1/0
  5. ping /n 1 1.1.1.1.1.1
  6. -&abcdefgh
  7. cd /d abc:\def
  8. echo %123%
  9. echo bathome>con 5>con
  10. echo 句柄真神奇!
  11. pause>nul
复制代码
运行的结果是不是出人意料,在“echo 表演开始罗 :>con”“和echo bathome>con 5>con”之间大家熟知的各种信息包括错误信息全部石沉大海不见踪迹,而屏幕上仅仅显示了“表演开始罗 :”“bathome”“句柄真神奇”这三句信息。那么这究竟是怎么回事呢?这代码中的1 2 3 4 5又是什么东西呢?咱们往下走。。。

    相信看过了论坛关于句柄重定向等贴子的会员都知道1 2 3 4 5这5个数字在代码中都是代表着句柄,而con是指标准输出或输入设备(在这里理解为屏幕)。关于句柄备份和重定向,论坛虽已经有专贴对其进行了详细的说明。但由于句柄这个东东确实难,老鸟理解起来都感觉吃力,更别说什么新人了。因此本人以自己的方法,结合以上的代码再对句柄及其作用进行一次描述说明。

    首先,我们要知道句柄有10兄弟(0-9),其中0 1 2三个人是有工作的,而且都是干公务员的(为什么这么说下面自有理论哈)。而3-9几位平常都是无业游民,出入于杂铺流留于市井。“我靠!你小子竟敢数落洒家,看打。。。”9的气已不打一处而来,顺手抄起一西瓜皮就甩将过来。。。我躲!还好老子还练过。大家看到了不,我没说错吧,他们平常就是氓流哈。“嗖。。。”8的鞋也飞过来了,我再躲。。。好了,咱就先别惹这几个家伙了(很明显3 4 5 6 7也纷纷抄鞋怒视于我)。我们先来讲讲身为公务员的0 1 2三号兄弟吧。0从事的职业跟大家是最密切同时也是最为大家所忽视的。大家都是用键盘进行输入的吧,0默认接收键盘(con)的输入到屏幕(至于包不包括语音输入和手写输入我就不知道了,汗水!)。大家在cmd上键入“copy con>a.txt”,然后下面输入的每一个字符(包括回车换行符)都会重定向输出到a.txt中,直到你用ctrl+c结束命令(大家利用这点可以直接在cmd上生成bat哦)。此时0的工作就由0和>共同承担了(既输出到屏幕又输出到a.txt。“当然了,老子一个做不会闷死啊,我也得拖个下水是不?”0看来很得意很公务员。。。那么1和2他们又是从事什么工作的呢?1分管的是将程序运行的正确信息输出(标准输出),而2分管的是将程序运行中的错误信息进行输出(标准输出)。我们平常所常见的1>nul 2>nul,实际上就是把所在行所有的标准输出都屏蔽掉。其实1和2也很公务员,他们有时也并不是那么敬业,会将自己的工作丢给3或4或5或。。。如上面的代码所示,2想“偷得浮生半日闲”,便通过大叔(>重定向符)将自己的工作交给下一个兄弟3,当然3也不是省油的灯,还想着如何跟2哥理论理论。。。“你想偷懒,没门,给我好好工作!”2早就看出了3的心思并以兄长的口吻教训了3,3只得将2剩下的工作老老实实接了下来,但他却很有本事,将错误输出通过大叔(>)一股脑一次重定向到nul(nul是指空设备,大家就理解为cmd中的黑洞了),大家注意到这个重定向是第一行中一次完成,不得不说3确实厉害(其实3-9都有这本事)。这时1觉得不公平了,为什么我不学学2呢?接着他又重复了2的操作,可是3没办法接替两位兄长的工作啊,于是1看到了老实的4(也只能是4因为3后面是4)。。。“小4过来,哥有事找你。”“哥有啥事啊?”小4哪敢怠慢,马上跑将过来。“是这样,哥有事要出去下,你就先帮我完成下工作吧。”1说完便也没管4愿与不愿,径自出得门庭找9去了。没办法,兄命如父命啊,小4只好将1的工作全接了下来,他也学3将正确输出通过大叔(>)一股脑一次重定向到nul(这小子太没头脑了,身为长辈的>在心中暗暗骂到)。的确,3是将错误信息丢给了黑洞nul,4你怎么将正常的显示信息也丢给了黑洞。这时他们的大叔>看不下去了,于是再次出马将第二行的信息重定向到了con(屏幕)。但是大叔也很忙,他做完了一行的工作就去打牌了(原来是这样忙的。。。)。于是,后面所有的信息无论错误还是正确,都被3和4丢入了黑洞(nul)之中。。。

    这时,早有人去cmd那里告状了,cmd马上找到了打牌的>和5(只能是5因为4后面是5。。。),通过他们的共同努力终于恢复了正常的输出。。。如果大家还没看明白,就再去读读论坛其他关于句柄备份的贴子吧。

ps:实际上@echo off 2>&3 3>nul&@1>&4 4>nul可以写成@echo off 2>nul 3>nul&@1>nul 4>nul也是一样的。
   它也相当于vbs中的on errer resume next(忽略一切错误),不知道说对了不。。。
***共同提高***

  1. @echo off >con 2>con 3>nul 4>nul
  2. echo 表演开始罗 :>con
  3. echo 看见我了吗?
  4. set /a a=1/0
  5. ping /n 1 1.1.1.1.1.1
  6. -&abcdefgh
  7. cd /d abc:\def
  8. echo %123%
  9. echo bathome>con 5>con
  10. echo 句柄真神奇!
  11. pause>nul
复制代码

TOP

异曲同工
  1. @echo off 2>&3 3>nul >con 5>nul
  2. echo 表演开始罗 :>con
  3. echo 看见我了吗?
  4. set /a a=1/0
  5. ping /n 1 1.1.1.1.1.1
  6. -&abcdefgh
  7. cd /d abc:\def
  8. echo %123%
  9. echo bathome>con 4>con
  10. echo 句柄真神奇!
  11. pause>nul
复制代码

TOP

这个~~故事太长,我看前面就放弃中间的了,直接看结局。。。。。。。
说实话的,我喜欢那些用术语的文章,越复杂我就越有兴趣慢慢磨,(前提是我真的需要这方面)
其次到图型说明,有时候出现一些图表说明各参数的变动最直接的,那种一看就明白

TOP

已经将楼主扣4分,但似乎与原有评分(也是加4)相抵,由于未知原因未能直接显示出来...
有图为证:
1.jpg是我的评分选项截图,2.jpg是batman收到的消息截图
以此证明确实扣过分

再次声明论坛不提倡使用违规标题,违者扣2分并屏蔽回复,管理层违规将加倍扣分!
希望广大会员引以为戒
1

评分人数

    • batman: 扣得好!还可以扣重点。。。PB + 2

TOP

感谢楼上两位的提醒,标题已经重新更改,只是本人无法扣自己的分,请路过的版主代劳。。。

你们这种维护论坛的秩序的行为是很好的,继续坚持哈。。。。
***共同提高***

TOP

11# batman

蝙蝠侠你好,我也觉得你的标题太笼统了,加了“神奇的”还是很笼统。
2

评分人数

    • zm900612: 监督管理层,应该双倍加分,补足4分PB + 2
    • batman: 欢迎继续监督PB + 2

TOP

请问楼上哪点违规了,如果有,我马上改。。。
***共同提高***

TOP

1# batman


想问下版主,你这个标题是不是也属于标题违规
2

评分人数

    • zm900612: 监督管理层,应该双倍加分,补足4分PB + 2
    • batman: 问得好!PB + 2

TOP

要想恢复1和2到原始的con。只需要改变3和4就可以。

即 1>1.txt 2>1.txt 3>con 4>con即可以回复正常。

TOP

7# applba

那句其实写成这样就可以了:
  1. @echo off>nul 2>nul 3>nul 4>nul
复制代码
楼主把1和2分开大概是为了明确句柄备份的流程吧...

TOP

@echo off 2>nul 3>nul&@1>nul 4>nul

这个不是句柄备份引发的血案吗?

执行前:
1备份到3,2备份4,3备份到5,4备份到6
执行后:
1从3回复为nul,2从4回复为nul,3从5回复为con,4从6回复为con。

TOP

5# batman


那是从你代码中的%123%引发的思考,应该不算离题吧...

TOP

我晕,楼上这贴跟得。。。

是啊,这就是变量名为什么不能以数字开头的原因,因为cmd会首先将%+数字预处理为%0-%9的参数。。。
***共同提高***

TOP

发现一个诡异现象,想了半天才明白原因
  1. set str=%934afsd%
  2. echo %str%
  3. call echo %%%str%%%
复制代码
很奇怪吧?为什么命名没有值的变量名会被被解释为去掉一个数字后输出剩下的字符串
绞尽脑汁才想通,原来
set str=%934afsd%
被解释为
set str=【%9】【34afsd】【%】
用!!就不存在这个问题,这问题的根本原因是cmd中参数的优先级高于变量,所以会出现这个“诡异”现象

TOP

返回列表