六、cmd运行机制篇
1、预处理机制:特殊字符优先级、语句和语块的划分
setlocal enabledelayedexpansion
(set n=3
set /a n=2,n=%n%+!n!+n)
::利用预处理机制,将一个变量解释为多个值
复制代码
setlocal enabledelayedexpansion
echo ^^!
::当语句中存在变量延迟符号时,将被预处理两次,这是一定要注意的
复制代码
set str=.
set "str name=str"
for %%a in (%tmp%) do if defined %%a echo %%a 存在变量str
::利用for的参数变量在if参数划分之后才被解释的特点,弥补if defined对于空格变量名的兼容性缺陷,
本质原因是for和if都是特殊的函数,他们的参数设置在语块的预处理中就已经被cmd“记住”了,之后无法
对其进行改变。
复制代码
(del %0
echo 能找到我,就给你发糖
pause>nul)
::括号里的内容被理解成一个语块,运行其中的命令时不需从文件读取,所以就算删除自身仍可运行。
复制代码
echo "test&pause|sort
::当一行命令中存在奇数个双引号时,将会转义其后所有本行字符
复制代码
for /f tokens^=2delims^=^" %%a in ("123"test"456") do echo %%a
::通过对特殊字符的转义,在for中用双引号当分隔符
复制代码
for /f tokens^=2delims^=^" %%a in (^"123"456") do echo %%a
set /p=^"""<nul
::当一组字符串中含有奇数个双引号时经常会出错,解决方法是转义其中的一个,保持有效的双引号成对,
可是引号对之内无法用转义符对其转义,所以转义符要放在引号对之外使用
复制代码
set /a "1/(%random%%%2)"&&set com=||set com=/f "tokens=2"
for %com% %%a in ("123 234 345") do echo %%a
::假如随机值为偶数,则显示指定字符串第二段,否则显示整段。这里用变量来定制命令,会比常规办法(
一条if和一条命令对应)更灵活和省事,但是要注意的是,变量延迟是在解释语块之后进行,所以这里
的%com%不能使用变量延迟。
复制代码
set /a \test1=123,test2=234
(
@echo off
for /f "tokens=1* delims==" %%a in ('set\') do echo %%b
)|sort
::sort对for命令的输出进行排序,那个
@echo off并非多余,因为通道之前的若是语块(for、if或者被成
对括号包起来的语句),该语块中的内容将会以cmd /c的形式运行,此时的回显是打开的,而变量延迟则是
默认关闭的。
复制代码
dir /ad 123\&&md234||rd 345&tree /f|more
::当存在123文件夹时,创建234文件夹,否则删除345文件夹,无论结果如何,接下来都会逐屏显示当前目
录树。重点是管道命令、逻辑连接符的灵活运用
复制代码
2、句柄的妙用
@echo off 2>nul 3>nul
这个命令不存在...
echo 错误回显呢?
pause
::句柄备份,可用于屏蔽所有正确或错误回显
复制代码
cd.>1.txt 2>2.txt 3>3.txt 4>4.txt 5>5.txt 6>6.txt 7>7.txt 8>8.txt 9>9.txt
::用一个命令创建9个文件,效率自然提高了
复制代码
@echo off
(for /r %%a in (*.*) do del /f /s "%%~nxa" 3>>"%%a") 2>nul 4>>%0
pause
::利用写入句柄会占用文件的特性实现高效删除重复文件