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

众所周知,如果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)命令,看看命令中是否有某些字符(如图):


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

再来解释一下为什么echo.有时候会引起错误。文件名中是不能出现:.\的,理论上GetFileAttributes函数都应该返回-1(INVALID_FILE_ATTRIBUTES),然而事实却不是如此,我也不知道这算不算GetFileAttributes函数的BUG:

复制代码 代码如下:

#include <stdio.h>
#include <windows.h>

int main()
{
FILE *fp = fopen("echo", "wb");
fclose(fp);
printf("0x%x\n", GetFileAttributes("echo:"));
printf("0x%x\n", GetFileAttributes("echo."));
printf("0x%x\n", GetFileAttributes("echo/"));
return 0;
}

如果你测试一下上面的C程序,就会发现echo.那行返回的不是-1。

如果GetFileAttributes函数返回的不是-1(一般表示文件不存在),也不是0×10(表示文件是文件夹),那么命令还是会保持原来的样子,当成外部命令运行。

复制代码 代码如下:

@echo off
cd .>echo
echo.
pause

‘echo.' is not recognized as an internal or external command, operable program or batch file.

复制代码 代码如下:

@echo off
cd .>echo
setlocal disableextensions
echo.
pause

关闭了CMD拓展,没有问题。

复制代码 代码如下:

@echo off
md echo
echo.
pause

echo是文件夹而不是文件,没有问题。

最后总结一下吧,在大部分情况下,你都应该使用第一组的echo, echo; echo=来进行输出,它们的效率跟echo (空格)是一样的,并且可以用来输出on或者off,在变量为空时还能输出空行。

但是echo, echo; echo=却不能输出以/?开头的行,如果你需要,可以使用第二组的echo+ echo/ echo[ echo],它们的效率低一些,但能保证原样输出。

我不建议你使用第三组的echo: echo. echo\,如果你仍然要像垃圾教程里面那样用,我也没有办法。
作者: Demon
链接: http://demon.tw/reverse/cmd-internal-echo.html

时间: 2024-09-30 20:29:38

批处理技术内幕 ECHO命令介绍_DOS/BAT的相关文章

dos命令介绍_DOS/BAT

DOS下的可执行文件有三种,分别是EXE,COM和BAT(当前页支持cmd扩展名).其中,EXE和COM文件都是二进制形式的,只有BAT文件是文本形式的,可以直接阅读.因此,BAT文件和以上二进制可执行文件相比,内容要简单的多.这些文件内包含着DOS命令的集合,通常叫作批处理文件. 批处理文件的组成虽然比较简单,但其用处非常大,使用也比较广泛.比如每次都执行一些相同的命令,您一定会觉得非常麻烦,而放在批处理文件中执行的话则轻松得多.AUTOEXEC.BAT就是一个特殊的批处理文件,它在DOS的启

批处理编程- -介绍_DOS/BAT

用批处理命令把一些特殊的文件按扩展名分类写到一份文件里.高中时代我最初接触到的就是DOS时代,我曾经也研究过批处理命令,但当时学得也不是很好,后来也看过一些过这方面的文章,但也没有进一步深入研究.基本上google,baidu上找不出来任何资料.今天又google,baidur查了一下,发现了好几篇文章(不过模板好像都是基于同一篇文章<简明批处理教程>,还是很少的,不过已经够用了哈. 原作出处已经找不到了,不过还是想转贴一下,实在是好东西,与公与私都要介绍一下: 批处理文件是无格式的文本文件,

windows批处理命令教程_DOS/BAT

批处理文件是无格式的文本文件,它包含一条或多条命令.它的文件扩展名为 .bat 或 .cmd.在命令提示下键入批处理文件的名称,或者双击该批处理文件,系统就会调用Cmd.exe按照该文件中各个命令出现的顺序来逐个运行它们.使用批 处理文件(也被称为批处理程序或脚本),可以简化日常或重复性任务.当然我们的这个版本的主要内容是介绍批处理在入侵中一些实际运用,例如我们后面要提到 的用批处理文件来给系统打补丁.批量植入后门程序等.下面就开始我们批处理学习之旅吧. 一.简单批处理内部命令简介 1.echo

Windows使用bat批处理实现守护进程脚本分享_DOS/BAT

本文转自网络,由于找不到原作者,因而无法知道出处.如果有幸让原作者看到,请联系我加上.先转载至此. 最近几天加班加疯掉了,天天晚上没法睡.开发部的一个核心程序总是会自己宕机,然后需要手工去起,而这个服务的安全级别又很高,只有我可以操作,搞得我晚上老没法睡,昨晚实在受不了了,想起以前在hp-ux下写的shell守护进程,这回搞个windows下的bat版守护程序吧,当时晚上思路已经很迟钝了,就叫了个兄弟让他写了,上去后运行效果不错,至少昨晚我安心睡了7小时.   早上来把程序改完善一些,增加了记录

xcopy 实现批处理拷贝文件或文件夹_DOS/BAT

xcopy 是一个很有用的doc命令,应该学习学习! 可以用xcopy实现,例如: C:\>xcopy C:\ppt\*.* D:\ppt\ /s /e 这条命令的意思就是把C盘下的PPT文件夹全部拷贝到D盘 XCOPY 还有众多的功能, 是加参数来完成的.上面的/s /e 参数的作用分别是把子目录和空目录都复制过去, 一些使用举例和参数说明如下: 1.如只是单纯地复制 E:\ 盘上所有文件到 D:\ 盘上,就输入" xcopy e:\*.* d: /s /h "就行啦!如果在复

收藏的比较完整的批处理教程第1/2页_DOS/BAT

一.批处理内部命令简介  1.Echo 命令  打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo 命令将显示当前回显设置.  语法  echo [{on|off}] [message]  Sample:@echo off / echo hello world  在实际应用中我们会把这条命令和重定向符号(也称为管道符号,一般用> >> ^)结合来实现输入一些命令到特定格式的文件中.这将在以后的例子中体现出来.  2.@ 命令  表示不显示@后面的命令,在入侵过程中(例如使

dos之bat批处理文件语法介绍_DOS/BAT

首先,批处理文件是一个文本文件,这个文件的每一行都是一条DOS命令(大部分时候就好象我们在DOS提示符下执行的命令行一样),你可以使用DOS下的Edit或者Windows的记事本(notepad)等任何文本文件编辑工具创建和修改批处理文件. 其次,批处理文件是一种简单的程序,可以通过条件语句(if)和流程控制语句(goto)来控制命令运行的流程,在批处理中也可以使用循环语句(for)来循环执行一条命令.当然,批处理文件的编程能力与C语言等编程语句比起来是十分有限的,也是十分不规范的.批处理的程序

批处理中常用的符号总结_DOS/BAT

^ 转义符   用在特殊符号之前 比如: echo 非常^&批处理 如果不加^ 那么"批处理"将被当作命令执行 | (管道)传递符 当然是传递作用 比如: echo 0123456 | find "123"  将0123456 传递给find 查找 123 || 连接符 当前面的命令没有成功执行 则执行后面的命令 比如: echo 0123456 | find "789" || echo 字符中没有789 &&  连接符

使用BAT批处理执行sql语句的代码_DOS/BAT

1.把待执行Sql保存在一个文件,这里为20110224.sql.2.新建一个扩展名.bat的批处理文件,输入下面命令并保存后,双击.bat文件,系统会自动执行20110224.sql的语句: 复制代码 代码如下: osql -S gdjlc -d TestDB -U sa -P 1 -i 20110224.sql osql参数见下面=======================================================================: E:\>osql