A. CMD的命令字符
@
\\隐藏命令的回显。
~
\\在for中表示使用增强的变量扩展;
在set中表示使用扩展环境变量指定位置的字符串;
在set/a中表示按位取反。
%
\\使用两个%包含一个字符串表示引用环境变量。比如一个%time%可以扩展到当前的系统时间;
单个%紧跟0-9的一个数字表示引用命令行参数;
用于for中表示引用循环变量;
连续的两个%表示执行时脱为一个%。
^
\\取消转义字符,即将所有转义字符的转义作用关闭。比如要在屏幕显示一些特殊的字符,比如> >> | ^等时,就可以在其前面加一个^符号来显示这个^后面的字符了,^^就是显示一个^,^|就是显示一个|字符了;
在set/a中是按位异;
在findstr/r的[]中表示不匹配指定的字符集。
&
\\命令连接字符。比如我要在一行文本上同时执行两个命令,就可以用&命令连接这两个命令;
在set/a中是按位与。
*
\\代表任意个任意字符,就是我们通常所说的"通配符";比如想在c盘的根目录查找c盘根目录里所有的文本文件(.txt),那么就可以输入命令"dir c:\*.txt";
在set/a中是乘法。比如"set/a x=4*2",得到的结果是8;
在findstr/r中表示将前一个字符多次匹配。
()
\\命令包含或者是具有优先权的界定符吧,比如for命令要用到这个(),我们还可以在if,echo等命令中见到它的身影;
-
\\范围表示符,比如日期的查找,for命令里的tokens操作中就可以用到这个字符;
在findstr/r中连接两个字符表示匹配范围;
-跟在某些命令的/后表示取反向的开关。
+
\\主要是在命令里面会用到它,表示将很多个文件合并为一个文件,就要用到这个+字符了;
在set/a中是加法。
|
\\管道符。就是将上一个命令的输出,作为下一个命令的输入."dir /a/b | more"就可以逐屏的显示dir命令所输出的信息;
在set/a中是按位或;
在帮助文档中表示其前后两个开关、选项或参数是二选一的。
:
\\标签定位符,可以接受goto命令所指向的标签。比如在批处理文件里面定义了一个":begin"标签,用"goto begin"命令就可以转到":begin"变迁后面来执行批处理命令了。
" "
\\界定符,在表示带有空格的路径时常要用""来将路径括起来,在一些命令里面也需要" "符号;
在for/f中将表示它们包含的内容当作字符串分析;
在for/f "usebackq"表示它们包含的内容当作文件路径并分析其文件的内容;
在其它情况下表示其中的内容是一个完整的字符串,其中的>、>>、<、&、|、空格等不再转义。
/
\\表示其后的字符(串)是命令的功能开关(选项)。比如"dir /s/b/a-d"表示"dir"命令指定的不同的参数;
在set/a中表示除法。
<
\\命令重定向符,将其前面的命令的输出结果重新定向到其后面的设备中去,后面的设备中的内容被覆盖。比如可以用"dir > lxmxn.txt"将"dir"命令的结果输出到"lxmxn.txt"这个文本文件中去;
在findstr/r中表示匹配单词的右边界,需要配合转义字符\使用。
>>
\\命令重定向符。将其前面的命令的输出结果重新定向到其后面的设备中去,后面设备中的内容没有被覆盖。
<
\\将其后面的文件的内容作为其前面命令的输入。
在findstr/r中表示匹配单词的左边界,需要配合转义字符\使用。
=
\\赋值符号,用于变量的赋值。比如"set a=windows"的意思意思是将"windows"这个字符串赋给变量"a";
在set/a中表示算术运算,比如"set /a x=5-6*5"。
\
\\这个"\"符号在有的情况下,代表的是当前路径的根目录.比如当前目录在c:\windows\system32下,那么你"dir \"的话,就相当与"dir c:\"
在findstr/r中表示正则转义字符。
''
在for/f中表示将它们包含的内容当作命令行执行并分析其输出;
在for/f "usebackq"中表示将它们包含的字符串当作字符串分析。
.
\\
在路径的\后紧跟或者单独出现时:
一个.表示当前目录;
两个.表示上一级目录;
在路径中的文件名中出现时:
最后的一个.表示主文件名与扩展文件名的分隔。
&&
\\连接两个命令,当&&前的命令成功时,才执行&&后的命令;
||
\\连接两个命令,当||前的命令失败时,才执行||后的命令。
$
\\在findstr命令里面表示一行的结束。
``
在for/f中表示它们所包含的内容当作命令行执行并分析它的输出。
[]
在帮助文档表示其中的开关、选项或参数是可选的;
在findstr/r中表示按其中指定的字符集匹配。
?
\\在findstr/r中表示在此位置匹配一个任意字符;
?在路径中表示在此位置通配任意一个字符;
紧跟在/后表示获取命令的帮助文档。
!
\\当启用变量延迟时,使用!!将变量名扩起来表示对变量值的引用;
在set /a中表示逻辑非。比如set /a a=!0,这时a就表示逻辑1。其他资料: 1、%是个ESCAPE字符,通常将之译为转义字符,但也有更形象的译名脱逸字符、逃逸字符等。也就是说%不仅仅将与其相关的特定字符串转义并替换为特定字符串,而且自身也会被“脱逸”。而且类似于C语言中的转义字符"\",双%会转义并脱逸为单%,四%则脱为双%。
2、for本身是一个特殊的命令,类似于一个特化的命令解释器,因为它的功能实现需要执行多条语句,因此它必须也具有对命令行(特指do后的命令行)分析处理的功能。而command/cmd实现for时自然会借用自身原有的命令行分析模块,因此for具有二级转义的特性,for中do后的语句被分两级分析和解释,第一级在command/cmd读入并解释for命令行时,第二级在for读入并解释do命令时,它通常会对同一命令行的进行多次解释。
然后,我们可以注意到,在do中使用命令行参数变量和环境变量时,不需要双%,那是因为,这些变量在经过第一级转义后,被替换成特定的不变的字符串常量,参与for循环的所有执行过程;而替代变量则要求在执行(do后的子命令行中)过程中不断的动态变化,而这个变化自然仍需要通过脱逸字符来实现,因此使用双%就是成了必然的选择。
另外,还需要注意到,在命令行中使用for时不需要双%,这源于命令解释器对命令行与批处理的处理方式不同。在早期的DOS版本中,%在命令行中不被视为转义字符,所以不会被转义和脱逸,所以当时无法在命令行直接引用环境变量。而使用for时,只需要一个%供for进行转义和脱逸就够了。在以后的命令解释器版本中,加入了命令行转义的支持(主要是环境变量的支持),但命令行for使用单%的传统仍然保留了下来。
而 cmd中的变量延迟替换是属于特殊的情况,但不违背以上的转义原则,只是for中的环境变量不再是常量了。
rmdir /S /Q %mhnet% 2>NUL 1>NUL 做简单解释
这句代码的大意是指将 %mhnet% 指定的目录删除,/s 代表删除其中的子目录, /q 表示删除目录树时不提示确认, 1>nul 表示将正确删除目录树的信息禁止输出,2>nul 表示将删除过程中的错误信息禁止输出
其中的1与2都是代表某个数据流输入输出的地址(NT CMD 称之为句柄,MSDOS称之为设备),下表(引自WinXP帮助文档“使用命令重定向操作符 (Redirection Operators”一节))将列出可用的句柄。
句柄 句柄的数字代号 说明
STDIN 0 键盘输入
STDOUT 1 输出到命令提示符窗口
STDERR 2 错误输出到命令提示符窗口
UNDEFINED 3-9 这些句柄由应用程序和各个具体工具单独定义
0 键盘输入
1 输出到命令提示符窗口
2 错误输出到命令提示符窗口
3-9 这些句柄由应用程序和各个具体工具单独定义。
2 > nul 表示程序出错的信息也不显示。
call attrib -r -h c:\autoexec.bat >nul
这句其实是:
call attrib -r -h c:\autoexec.bat 1 > nul
这些1,2,0等等都是句柄,说白了就是代号,你只要知道1是代表输出信息,2是代表出错信息,0是代表键盘输入就行了。
如果有什么不明白的可以多看看帮助与支持。
命令行对重定向符号出现的位置不做过多限定,只要重定向符号后紧随“字符设备”即可,故以下语句等效:
echo Hello World> hello.txt
echo Hello> Hello.txt World
echo> Hello.txt Hello World
> hello.txt echo Hello World
在NT系列命令行中,重定向的作用范围由整个命令行转变为单个命令语句,受到了命令分隔符&,&&,||和语句块的制约限制。
echo Message1> msg1.txt & echo Message2> msg2.txt
if "%target%"=="" (echo message to screen ) else (echo message to file> %target%)
综上所述,>nul 意为将此句命令所产生的标准输出请求重新定向到空设备中,而因为此设备的缄默特性,即相当于将此语句的输出信息屏蔽(并非隐藏);而 2>nul 则是将程序执行错误时的标准错误信息输出请求重定向后屏蔽。它们联合使用,即为将此语句所可能产生的所有输出信息屏蔽。
“重定向”是MSDOS起就存在的命令行特性,负责将指定命令或语句所产生的输入输出请求由缺省的“控制台”转交给其它的“设备”来完成,它的启动标志是“重定向符号”(包括“>,>>,<”三个,其各自意义见[1])出现在句中。
一般的命令行程序输入输出请求都通过内部定义三个“端口”(在NT下称为“句柄”,在DOS下未定义)来完成,分别为标准输入stdin、标准输出stdout、标准错误stderr。它们通常指向的设备为控制台(console,代码为CON),其中stdin指向控制台的键盘,stdout/stderr指向控制台的监视器。因此,控制台通常即指键盘与监视器的联合体,这是在早期大型机的终端机上所体现出来的概念。其中的stdin可被<重定向,stdout可被>、>>重定向,而stderr在DOS下不可直接重定向,只有通过ctty或其它命令将系统控制权转交给其它设备的方式,来间接完成。
“设备”是指可控制PC硬件或端口的设备驱动程序或端口代码,它通常由系统底层或硬件驱动程序实现和支持。比如IO.SYS实现的控制台CON、系统时钟CLOCK$、未知设备CONFIG$、第一串口AUX、第一并口PRN、所有串口COM1~COM4、所有并口LPT1~LPT3、可用盘符A:-X:以及上文提到的空设备NUL。还有许多其它设备,比如HIMEM.SYS实现的XMSXXXX0,EMM386.EXE实现的EMMXXXX0,IFSHLP.SYS实现的IFS$HLP$等。
在这些设备中,可以处理输入输出信息的很少,只有CON、NUL以及连接有输入输出硬件(打印机、MODEM等)的串口或并口设备。它们被称为“字符设备”,而磁盘文件也作为一种特殊的字符设备列选其中,这就大大扩充了重定向的自由度与实用性,以致很多人也将重定向称为“文件重定向”。
空设备NUL是一个特殊的设备,因为它没有可控制的PC硬件或端口,而只是一个虚构的的设备或端口,它仅存在于软件层面。正因为如此,它可以接受所有重定向的输入输出请求而不给出任何回应(在NT下不会给出任何输入信息而结束输入请求,在DOS下则反复填充127个字节0后终止响应),这种特性使它很像天文学上的能吞噬一切物质和信息的“黑洞”,也很类似哲学上能颠转阴阳无中生有的“玄玄之道”。它之所以存在,是因为我们需要一个可以默默无闻地无条件吸纳各种冗余输出信息或输入请求的“回收站”,正如“黑洞”就像一个巨大的“宇宙垃圾场”一样
CMD没有神经错乱,是set处理的整数太大了,set使用双字节存储整数,有32位的存贮范围限制,也就是说它的处理范围是2^-31~2^31-1,你的磁盘空间超过了这个范围溢出了。
对此我没有太好的解决办法,只有舍弃后三位后除以1049的近似算法。
for /f "tokens=3" %%a in ('dir /-c c:\^|find "可用字节"') do set freesize=%%a
set /a freesize=%freesize:~0,-3%/1049>nul
echo Freesize:%freesize%
> 创建一个文件
>> 追加到一个文件后面
@ 前缀字符.表示执行时本行在cmd里面不显示, 可以使用 echo off关闭显示
^ 对特殊符号( > < &)的前导字符. 第一个只是显示aaa 第二个输出文件bbb
echo 123456 ^> aaa
echo 1231231 > bbb
() 包含命令
(echo aa & echo bb)
, 和空格一样的缺省分隔符号.
; 注释,表示后面为注释
: 标号作用
│ 管道操作
; 符号当命令相同的时候可以将不同的目标用;隔离开来但执行效果不变。如执行过程中发生错误则只返回错误报告但程序还是会继续执行
首先, @ 不是一个命令, 而是DOS 批处理的一个特殊标记符, 仅用于屏蔽命令行回显. 下面是DOS命令行或批处理中可能会见到的一些特殊标记符:
CR(0D) 命令行结束符
Escape(1B) ANSI转义字符引导符
Space(20) 常用的参数界定符
Tab(09) ; = 不常用的参数界定符
+ COPY命令文件连接符
* ? 文件通配符
"" 字符串界定符
| 命令管道符
< > >> 文件重定向符
@ 命令行回显屏蔽符
/ 参数开关引导符
: 批处理标签引导符
% 批处理变量引导符
其次, :: 确实可以起到rem 的注释作用, 而且更简洁有效; 但有两点需要注意:
第一, 除了 :: 之外, 任何以 :开头的字符行, 在批处理中都被视作标号, 而直接忽略其后的所有内容, 只是为了与正常的标号相区别, 建议使用 goto 所无法识别的标号, 即在 :后紧跟一个非字母数字的一个特殊符号.
第二, 与rem 不同的是, ::后的字符行在执行时不会回显, 无论是否用echo on打开命令行回显状态, 因为命令解释器不认为他是一个有效的命令行, 就此点来看, rem 在某些场合下将比 :: 更为适用; 另外, rem 可以用于 config.sys 文件中.
也可以使用以下的用法:
if exist command
device 是指DOS系统中已加载的设备, 在win98下通常有:
AUX, PRN, CON, NUL
COM1, COM2, COM3, COM4
LPT1, LPT2, LPT3, LPT4
XMSXXXX0, EMMXXXX0
A: B: C: ...,
CLOCK$, CONFIG$, DblBuff$, IFS$HLP$
具体的内容会因硬软件环境的不同而略有差异, 使用这些设备名称时, 需要保证以下三点:
1. 该设备确实存在(由软件虚拟的设备除外)
2. 该设备驱动程序已加载(aux, prn等标准设备由系统缺省定义)
3. 该设备已准备好(主要是指a: b: ..., com1..., lpt1...等)
可通过命令 mem/d | find "device" /i 来检阅你的系统中所加载的设备
另外, 在DOS系统中, 设备也被认为是一种特殊的文件, 而文件也可以称作字符设备; 因为设备(device)与文件都是使用句柄(handle)来管理的, 句柄就是名字, 类似于文件名, 只不过句柄不是应用于磁盘管理, 而是应用于内存管理而已, 所谓设备加载也即指在内存中为其分配可引用的句柄.