Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1691889
  • 博文数量: 410
  • 博客积分: 9563
  • 博客等级: 中将
  • 技术积分: 4517
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-03 19:59
个人简介

文章分类

全部博文(410)

文章存档

2017年(6)

2016年(1)

2015年(3)

2014年(4)

2013年(32)

2012年(45)

2011年(179)

2010年(140)

分类: WINDOWS

2010-07-13 23:27:58

ps:windwos xp 下如果希望看批处理的帮助,在命令行里输入
HH ntcmds.chm


自从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
阅读(1896) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~