【原】[一日一教学]批处理系列帖子索引 http://bbs.bathome.net/thread-2576-1-1.html
【续】[一日一教学]批处理系列帖子索引 http://bbs.bathome.net/thread-13798-1-1.html
帮助信息:- 从批处理程序调用另一个批处理程序。
-
- CALL [drive:][path]filename [batch-parameters]
-
- batch-parameters 指定批处理程序所需的命令行信息。
-
- 如果命令扩展被启用,CALL 会如下改变:
-
- CALL 命令现在将卷标当作 CALL 的目标接受。语法是:
-
- CALL:label arguments
-
- 一个新的批文件上下文由指定的参数所创建,控制在卷标被指定
- 后传递到语句。您必须通过达到批脚本文件末两次来 "exit" 两次。
- 第一次读到文件末时,控制会回到 CALL 语句的紧后面。第二次
- 会退出批脚本。键入 GOTO /?,参看 GOTO :EOF 扩展的描述,
- 此描述允许您从一个批脚本返回。
-
- 另外,批脚本文本参数参照(%0、%1、等等)已如下改变:
-
-
- 批脚本里的 %* 指出所有的参数(如 %1 %2 %3 %4 %5 ...)
-
- 批参数(%n)的替代已被增强。您可以使用以下语法:
-
- %~1 - 删除引号("),扩展 %1
- %~f1 - 将 %1 扩展到一个完全合格的路径名
- %~d1 - 仅将 %1 扩展到一个驱动器号
- %~p1 - 仅将 %1 扩展到一个路径
- %~n1 - 仅将 %1 扩展到一个文件名
- %~x1 - 仅将 %1 扩展到一个文件扩展名
- %~s1 - 扩展的路径只含有短名
- %~a1 - 将 %1 扩展到文件属性
- %~t1 - 将 %1 扩展到文件的日期/时间
- %~z1 - 将 %1 扩展到文件的大小
- %~$PATH:1 - 查找列在 PATH 环境变量的目录,并将 %1
- 扩展到找到的第一个完全合格的名称。如果
- 环境变量名未被定义,或者没有找到文件,
- 此修改符会扩展到空字符串
-
- 可以组合修改符来取得多重结果:
-
- %~dp1 - 只将 %1 扩展到驱动器号和路径
- %~nx1 - 只将 %1 扩展到文件名和扩展名
- %~dp$PATH:1 - 在列在 PATH 环境变量中的目录里查找 %1,
- 并扩展到找到的第一个文件的驱动器号和路径。
- %~ftza1 - 将 %1 扩展到类似 DIR 的输出行。
-
- 在上面的例子中,%1 和 PATH 可以被其他有效数值替换。
- %~ 语法被一个有效参数号码终止。%~ 修定符不能跟 %*
- 使用
复制代码 .
命令概括:
call,意为: 电话;呼叫;要求;访问。引申为“调用”。
batch-parameter,意为“批处理参数”。
label,意为“标签”。
argument,意为“参数”。
call表明,批处理其实也是有函数的。
参数详解:
1、从批处理程序调用另一个批处理程序(外部函数)?
新建两个批处理程序,分别命名为test.bat、hello.bat。
test.bat复制代码 .
hello.bat- @echo off
- call test.bat hello world
- pause
复制代码 运行hello.bat,调用test.bat,结果显示。
.
从结果中可以看出,hello.bat执行了4条语句,第一条关闭回显(@echo off),第二条输出hello world,第三条、第四条暂停并提示(pause)。
从这里可以看出,从批处理程序调用另一个批处理程序的执行流程:先执行原批处理中的代码,当遇到调用时再执行完被调用的批处理中的所有代码,最后返回到原批处理再执行call语句之后的代码。这种执行流程,同样适用于call 调用标签(内部函数)
2.第一节test.bat中%1,%2是什么意思?
要明白test.bat中%1、%2是什么意思,我们得结合hello.bat中“call test.bat hello world”和test.bat中“echo %1 %2”来看。
hello.bat中的类容不变,试着修改test.bat中的内容。
test.bat复制代码 .
再次执行hello.bat,结果:复制代码 .
“hello”不见了,只显示了“world”,这给人一种感觉,好像%1代表了“hello”,%2代表了“world”——事实上也确实如此。
我们可以将%1~%9这九个参数看成是批处理的形参,在这个例子中,%1,%2就是形参,而“hello”、 “world”就是实参。
这种参数的传递,执行流程就是在原批处理中将实参传递到被调用批处理中的形参中。
例如:
将hello.bat,test.bat进行如下修改。
hello.bat- @echo off
- call test.bat 3 9
- pause
复制代码 .
test.bat- Set /a n=%1+%2
- echo %n%
- pause
复制代码 .
运行hello.bat,结果返回12。
实参中的分隔符可以是空格、逗号、分号、等于号,“call test.bat 3 9”写成“call test.bat 3,9”、“call test.bat 3;9”、“call test.bat 3=9”都是可以的。
3.调用一个内部函数(标签)
如果把“被调用批处理”看成是外部函数,那么标签就可以看成是内部函数。
修改hello.bat的内容:- @echo off
- call :1 "hello"
- pause
- exit
- :1
- echo.%~1
复制代码 .
call调用标签时冒号(:)不可以省略,和goto不同(goto跳转时,冒号可有可无)。
4.函数调用中非实参形参对应关系的变量值的相互传递。
hello.bat- @echo off
- Set n=1
- call :1 "hello"
- pause
- exit
- :1
- echo.%~1
- echo %n%
复制代码 代码的执行结果:复制代码 .
以上结果说明,内部函数中,变量n的值,可以在主函数中定义,在被调用函数中输出。——这种结果,同样会出现在外部函数中(一个批处理调用另一个批处理)。
再次修改hello.bat- @echo off
- call :1 "hello"
- echo %n%
- pause
- exit
- :1
- echo.%~1
- Set n=1
复制代码 .
结果:复制代码 以上结果说明,内部函数中,变量n的值,也可以在被调用函数中定义,在主函数中输出。——这种结果,同样会出现在外部函数中(一个批处理调用另一个批处理)。
5.嵌套调用
嵌套调用就是一个被调用的函数中还有一个调用其它函数的命令,就好像小时候玩的那工兵、班长、排长、连长、团长……,团长 call 连长,连长 call 排长,……,班长 call 工兵,然后工兵才开始干活。
修改两个批处理的内容:
hello.bat- @echo off
- call test.bat world
- echo %m%
- pause&exit
复制代码 .
test.bat- Echo %1
- Set m=1
- call :1 hello
- pause&exit /b
- :1
- echo %1
复制代码 .
结果:- world
- hello
- 请按任意键继续. . .
- 1
- 请按任意键继续. . .
复制代码 .
这里,test.bat是被调用的函数,但它自身又包含一个内部子函数(:1)——这就是函数的嵌套。
可以看出虽然test.bat中有两个%1,但是它们的值并不相同,这说明父函数的形参并不等于子函数的形参。
注意:这里exit /b 是用来退出子函数的,不加/b参数就会退出整个cmd.exe(区别就是,加/b父函call之后命令还会执行,不加/b父函数call之后的命令就不会执行了)。
可以把test.bat中的exit /b 替换为 exit 体会一下。
6.函数的递归调用
http://bbs.bathome.net/thread-1264-1-6.html
这篇教程由pusofalse提供。
扩展阅读:
1.利用call实现变量延迟。- @echo off
- for /l %%i in (1 1 5) do (
- Set n=%%i
- set /a n+=1
- call echo %%n%%
- )
- pause
复制代码 .
2.call和for一起使用。- ::在文件路径前加“this is a text”
- @echo off
- For /r %%i in (*.txt) do call :1 %%i
- pause
- :1
- Set n=This is a text:%1
- echo %n%
复制代码 .
第二种方法的作用其实更大。但是第一种方法用的却更多。 |