ps:windwos xp 下如果希望看批处理的帮助,在命令行里输入
自从choice被从windows命令行工具中拿
掉之后,一直以为Windows的批处理没落了。后来知道Windows Scripting
Host之后,更加肯定了这个感觉。微软曾经试图开发一个被称作PowerShell的命令行程序,但是最终被cancel掉。我心里在慢慢
为.bat/.cmd文件超度。但是,最近的学习却大大改变了我的看法。本来以为批处理的能力有较大弱化,其实不然。
在Windows
9x之前,choice一直是一个很强大的用户输入工具。没有了它,批处理与用户的交互就麻烦得多。但事实上,在2000之后有另一个命令替代了
choice的功能,虽然不如choice那样强大:set。新的set不仅可以从stdin读入,利用重定向功能,还可以从文件中读入。set将读到的
内容赋给一个指定的变量,这在9x之前是不易做到的。不仅如此,set还具有一个简单的数学计算功能:set /a
8-5将输出一个3。这对于批处理也是非常有用的。
下面是XP上的一些批处理功能:
1.
复合语句:可以用圆括号将很多语句扩起来,整个圆括号中的语句将被视为一个语句。这常用于if、for语句之中。复合语句中的语句必须分别在不同的行。如
果需要在同一行中写两个语句,可以使用&将其连起来。
2. 分支和循环语句:if
语句在打开扩展功能之后还可以进行大小的比较,而不仅仅是相等的比较。for语句可以用来进行指定量的循环,也可以用来解析字符串,甚至可以遍历目录以及
子目录。
3.
子程序:这是call命令的一个增强。旧的call命令只能用于批处理文件的调用。而增强后的call可以用来对加标签的命令行进行调用: call
:subroutine。其后也可以加上参数。关于子程序的退出,goto语句有一个特殊的用法:goto
:eof。使用这个将直接跳到批处理文件尾,从而回退到主程序中,而无论是否有定义eof标签。
4.
局部变量:使用setlocal/endlocal可以构建一个局部命令行环境。已有的环境变量定义在局部环境中仍然存在。但对它们的修改在
endlocal语句之后就将失效。这相当于提供了局部变量的功能。对子程序来说,这是很有用的功能,再也不用担心变量污染问题。但这也意味着子程序无法
拥有返回值。解决这个问题的方案似乎只有一种办法:将返回值写入到文件之中,再由主程序读回来。
5.
延迟展开:这个需要进行稍微细致一点的解释。
延迟展开默认是关闭的。使用setlocal
enabledelayedexpansion可以启用这个功能,或者在启动cmd.exe时加/v。XP批处理中语句执行的一个特点是:在具体执行前,
其中的变量都已经被替换成相应的值。比如:
set var=global
if "%var%"=="global" (
set var=local
if "%var%"=="local" echo local
)
在上面的例子中,测
试"%var%"=="local"将永远为假,尽管看起来,在之前有对var重新赋值。但是,请记住,批处理中的语句在执行前就必须做完全展开。这意味
着%var%被全部替换成为了global。所以,实际执行的语句是:
if "global"=="global" (
set
var=local
if "global"=="local" echo local
)
这大概不是想要的结果。为了能够
使得上面的语句按预期的方式执行,就必须打开延迟展开功能。相应的,想要进行延迟展开的变量必须使用!var!的形式来引用:
set
var=global
if "%var%"=="global" (
set var=local
if
"!var!"=="local" echo local
)
这样,!var!就不会在整句执行前就做变量展开,而是在变量被使用的时候才
去进行展开替换。对于复合语句来说,这是一个非常有用的功能。否则,复合语句以及if、for的能力将有限很多。
另外,XP下还有一些有
用的工具:
1.
字符串查找:find/findstr。其中findstr可以用正则表达式来查找。配合type、for使用常常可以获得很强大的能力。
2.
注册表读写:reg。能查找、读取、写入、删除注册表中的键或值。有了它,就不用再很辛苦地使用regedit和find/findstr来查询注册表
了。
3. 文件关联:assoc/ftype。两者配合使用,可以很轻松的进行文件关联。比使用reg要容易得多。
4.
目录转换:pushd/popd/cd。pushd可以将当前的目录保存,并切换到指定的目录中。使用popd则可以回退到上一次目录中。另外,cd有一
个小小的增强。旧版的cd仅能够切换目录,而无法切换盘符。在XP中使用cd /d则可以同时进行切换。这个增强方便了不少。
5.
程序启动:start。默认情况下,启动GUI程序将不会阻塞批处理程序。这有时不是想要的。使用start
/w则可以解决这个问题。当然start还有其他的用法,这里就不提了。
最后,关于字串处理。因为环境变量实际上都是字符串作为值,所以
对字符串有一定处理能力是很有用的。这方面XP的批处理并不很强,但不是没有。环境变量在XP下有一些非常有趣的引用方式:
1.
取子串:%var:~3,5%。将返回变量var的子串,起始位置为3,长度为5。位置从0开始,而-1将折回串尾。没有指定长度,则到串结束为止。负的
长度也将从串尾开始折回:%var:~3,-5%表示从第3位开始,到倒数第5位结束。
2.
替换子串:%var:str1=str2%。将var中所有的str1用str2来替换。
请注意,如果var没有定义,结果将不是所预期的。所
以,在进行串处理之前,最好判断变量是否为空。
另外,关于参数的展开、重定向等还有一些扩展。这里就不提了。
一段示例代
码:
:://////////////////////////////////////////////////////////////////////////////
:: A demo script.
:://////////////////////////////////////////////////////////////////////////////
::--- Main ---
@echo off
setlocal EnableExtensions
EnableDelayedExpansion
if /i "%1" =="if" (
echo in then statement
echo.
) else (
echo in else statement
echo.
)
for /f "tokens=4 delims= " %%a in ("k1 k3 k4
k5 k7 k9") do (
if "%%a"== "k5" echo
in for keyword statement, key=%%a
)
set combine=
for /l %%a in (1,1,10) do (
echo in for loop
statement, num=%%a
set combine=!combine!%%a
)
echo delayed expansion result: %combine%
echo.
call :subdemo %1
goto :end
::--- Main end.
:end
endlocal
echo on
@goto :eof
::--- Local routines go here.
--------------------------------------------------
::--- subdemo ---
:subdemo
setlocal
echo in subroutine
if not "%*"=="" echo subroutine parameter(s):
%*
echo.
endlocal
goto :eof
资源:
windows->start->help
and support->search "batch files"->suggest topics->batch files
windows->start->run->cmd.exe->help
阅读(1960) | 评论(0) | 转发(0) |