(批处理学习)句柄备份——个人见解之“>nul 3>nul“——记录学习过程(详细)

目录

发现问题

猜测原因

尝试1

尝试2

查询资料

分析

特别的

应用

解决办法(不完全)

缺陷

缺陷1

缺陷2

最佳策略

参考资料




 


使用的系统:(注:以下的探究过程均属于该计算机

 


 

发现问题

最近学习批处理时,因手误打错了一个数字,然后发现了一个问题(引起深思......):

@echo off
echo 计时器准备就绪
echo 按键开始
pause >nul
echo 请等待约5秒
ping 127.1 -n 5 >nul 3>nul
echo 时间到
echo 按键退出
pause >nul

本来想弄个简单的计时器,结果程序未显示“时间到”和“按键退出”的字样,后来检查时发现

"ping 127.1 -n >nul 2>nul"打成了"ping 127.1 -n >nul 3>nul"

猜测原因

尝试1

改回来后,不禁有些疑问,于是又在命令提示符(cmd)中进行几次测试:

echo. >nul 3>nul
echo hello world
echo hi world

分别依次键入以上的代码,显而易见,之后的“hello world”和“hi world”被屏蔽了

试着输入

echo on

结果并未恢复

由此可见,“>nul 3>nul”并非等价于“echo off”。

尝试2

在尝试“echo off”无效后,我试着故意键入一些代码(正确的错误的都有),如“cls”“abcd”等,发现若为错误代码将会报错,正确的反而没有反应(例如:"cls"会清屏失败)

 由此可见,批处理屏蔽了“正确的命令”而不执行,但是遇到“错误的命令”会报错。

查询资料


在网上搜索“>nul 3>nul”,发现早已经有人发现了这现象,并给出了解释(句柄备份)

(原文链接在参考资料处,有兴趣的可以去看一下)


这里列举一下句柄:(注:下表的“STD”即“Standard”,意思为“标准”)

批处理的可用句柄
句柄STDINSTDOUTSTDERRUNDEFINED
句柄号 0123~9
说明

标准输入

(默认:从键盘输入)

标准输出

(默认:输出到命令提示符窗口)

标准错误输出

(默认:输出到命令提示符窗口)

未定义的句柄

(需要由用户或应用程序自行定义)

分析

下面拿个简单的例子来说明:

pause>nul

后面的“>nul”的作用就是屏蔽了 pause 命令的默认输出 “请按任意键继续. . .”

以上是简单的描述,而实际的过程可没那么简单


首先确定重定向符号为 >

接着检查句柄号,发现没有,控制台为其加上默认句柄 1,此时变成 pause 1>nul

由于句柄 1 的默认指向 con,此时要被临时设定为指向 nul,为了之后取回原来的指向,所以要

对 1 的指向进行备份(备份原则:备份到“句柄3~9”中的第一个空句柄中),备份到句柄 3,备份过后临时设定 1 指向 nul

到这时这条语句才被执行(效果就是批处理暂停),然后只有一个下划线闪来闪去


后面的是重点还款原则:我有欠条,你必须得还我钱。


执行完后 1 要取回原来的指向

1 的指向在上面被备份到 3

不管 3 的指向有没有改变 1 要取回它的指向来 (还款原则)

取回后 1 指向 con

3 的指向被取走

由于 3 没有备份

所以恢复到原来的状态(即:“空”状态,无指向)

至此整个过程描述完毕


可以发现这时的情况与最初是相同的

所有句柄的指向都是其默认值。

特别的

echo hello >nul >hi.txt >prn >con

在上面的例子中,“>nul”“>hi.txt”“>prn”“>con” 因为都是使用句柄1,所有前面的会被后面的取代可以理解为只看最后一个使用句柄1的“>con”


 即:单一命令行重复使用相同的句柄时,遵循“覆盖原则”:前面的会被后面的取代


echo hello 1<&3 >nul

同样的,在上面的例子中,会以“>nul”为准,即屏蔽hello(不显示hello)

应用

屏蔽错误(可用于批处理或cmd终端)


形式:命令+2>nul 3>nul


例如:

cls 2>nul 3>nul

解决办法(不完全)

分析过后,我也得出来一些结论:

对于“>nul 3>nul”的问题,解决办法治标不治本,可以输入“命令+>con 4>con”,例如:

echo.>con 4>con

当然,如果你刚开始输入的是“命令+>nul 2>nul 3>nul”(效果:无论命令是否正确,都屏蔽回显

那么,就得输入“命令+>con 2>con 3>con 4>con”了

总之,具体问题具体分析。

缺陷

前面也已经提及了这解决办法“治标不治本”,那么有哪些缺陷呢?

(注:以下缺陷的“造成原因”及其“完美处理办法”尚待解决)

缺陷1

一旦你键入了“>con 3>con”,即使你键入“>con 4>con”,也会有一个明显的特点(大概率出现)


 当你输入“cls”命令时,不会清除屏幕

而且还会显示一个“♀ (象征女生的符号,也是金星的符号)


猜测:可能是有句柄转换引起的编码错误

已尝试的方法:

1.转义:使用"转义符号^"后,缺陷1未消除

2.批处理:在批处理(.bat)文件中,缺陷1未消除


 这一点对大多数人可能毫无影响,但是对强迫症可就有些不友好了(例如笔者本人)

缺陷2

使用后,会对未定义的句柄进行定义,(句柄0~9会有对应的">con"或">nul"标签)

在某些时候可能会影响重定向符的效果

不过,也不必太过担心。如果“编写的批处理文件很简单,没有涉及到复杂的重定向过程”或者“对类似的代码语句多加注意”,一般也不会造成太大的影响

最佳策略

如果不是在处理重要的批处理文件,遇到这种问题的最佳策略无非是:


及时保存(备份文件)——>修改错误的代码——>重新打开文件——>避免同样的错误


是的,看起来很简单,因为对“句柄”的修改一般不会一直有效(就像一次性的环境变量一样)

及时备份,修改错误的部分,便又可以继续使用了

参考资料

1.批处理重定向中的秘密(句柄备份) - BAT教程&资料 - 批处理之家 批处理_BAT脚本_PowerShell_VBS_CMD_DOS_Perl_Python - Powered by Discuz! 批处理之家 看了 [ 小竹英雄 ] 的 “重定向中的秘密” 一文,搞得我云里雾里,真就是那饭桌上的美食转哪转——晕菜了。所以写此文与各位看看,有什么不对的地方请大家指正 ... - Discuz! Boardicon-default.png?t=LA92http://bbs.bathome.net/thread-2579-1-6.html

2.批处理之命令重定向操作_飞鹤的程序员人生-CSDN博客_批处理 重定向1. 介绍命令重定向操作符 (Redirection Operators)可以使用重定向操作符将命令输入和输出数据流从默认位置重定向到不同的位置。重定向操作符说明>将命令输出写入到文件或设备(例如打印机)中,而不是写在命令提示符窗口中。<从文件中而不是从键盘中读入命令输入。>>将命令输出添加到文件末尾而不删除文件中的信息。&g...https://blog.csdn.net/feihe0755/article/details/90181822?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163801008016780271923509%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163801008016780271923509&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-90181822.first_rank_v2_pc_rank_v29&utm_term=%E6%89%B9%E5%A4%84%E7%90%86%E5%8F%A5%E6%9F%84&spm=1018.2226.3001.4187

                                                                                                                          ——(全篇完)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值