首页 > 编程 > BAT > 正文

批处理技术内幕 ECHO命令介绍

2020-06-09 13:53:56
字体:
来源:转载
供稿:网友
众所周知,如果echo后面跟一个环境变量,但是该变量却为空时,相当于不加任何参数的echo,即输出当前echo是on还是off。很多文章或者教程给出的解决方案都是在echo后面加一个点号echo.,这样就会输出空行。
代码如下:
@echo off
echo %demon.tw%
:: ECHO is off.
echo.%demon.tw%

pause据我所知,用echo输出空行至少有十种方法:
代码如下:
@echo off

echo=
echo,
echo;

echo+
echo/
echo[
echo]

echo:
echo.
echo/
pause

这十种方法可以分为三组,每组的效率依次递减。可悲的是,那些被奉为经典的教程给出的却是效率最低那组中的echo.

echo.不仅效率低下,而且还容易引发错误:
代码如下:
@echo off
cd .>echo
echo.
pause

我知道你很难接受,但事实的确如此。

第一组中echo后面的=,;都是批处理中的分隔符,所以CMD可以正确地解析出echo命令,并把=,;作为echo命令的参数。是的,你没有看错,分隔符并不是用来分隔命令与参数,它们通常是参数的一部分。既然是参数,那么为什么不会被输出?那是因为echo命令直接跳过了参数的第一个字符,从第二个字符开始输出,而第二个字符是NUL,所以输出了空行。

你可能又要问,那为什么用空格做分隔符却不能输出空行呢?那是因为在输出之前,CMD要检查echo命令的参数是不是on或者off,或者参数为空:首先跳过所有空白字符,如果跳过之后字符串就结束了,那么就认为没有加参数,输出echo是on还是off;如果字符串没有结束,就调用wcsnicmp函数来判断剩下的字符串是否为on或者off,进而修改echo的状态。

因此加上很多空格也是一样的效果:
代码如下:
@echo off
echo
echo on
echo
pause

而对于第二和第三组,事情就没那么简单了,由于echo后面跟的并不是分隔符,所以解析之后会被当成一个整体,而echo+ echo/等等显然又不是内部命令,CMD会把它们当做外部命令进行搜索。嗯,你知道,搜索是很花时间的,这就是为什么它们的效率低于第一组。

可惜的是,CMD花了很大力气搜索,却仍然找不到这样的外部命令,这时候它会尝试着修复(Fix)命令,看看命令中是否有某些字符(如图):

FindAndFix
可以看到,CMD对:./的处理跟+[]/不太一样,如果是+[]/,CMD会直接把它们从命令中删除并且添加到原有参数的前面;而如果是:./并且CMD拓展是开启的话,那么会多调用一次GetFileAttributes函数获取文件属性,多调用一次函数自然会多花一些时间,所以第三组的效率又稍稍比第二组的低些。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表