[批处理命令一日一教学 续](41)调用子过程或外部程序:call
【原】[一日一教学]批处理系列帖子索引 [url]http://bbs.bathome.net/thread-2576-1-1.html[/url]【续】[一日一教学]批处理系列帖子索引 [url]http://bbs.bathome.net/thread-13798-1-1.html[/url]
[color=Green]帮助信息:[/color][code]从批处理程序调用另一个批处理程序。
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 可以被其他有效数值替换。
%~ 语法被一个有效参数号码终止。%~ 修定符不能跟 %*
使用
[/code].
[color=Green]命令概括:[/color]
call,意为: 电话;呼叫;要求;访问。引申为“调用”。
batch-parameter,意为“批处理参数”。
label,意为“标签”。
argument,意为“参数”。
call表明,批处理其实也是有函数的。
[color=Green]参数详解:[/color]
1、从批处理程序调用另一个批处理程序(外部函数)?
新建两个批处理程序,分别命名为test.bat、hello.bat。
test.bat[code]
echo %1 %2
pause[/code].
hello.bat[code]@echo off
call test.bat hello world
pause
[/code]运行hello.bat,调用test.bat,结果显示。
[attach]4730[/attach].
从结果中可以看出,hello.bat执行了4条语句,第一条关闭回显(@echo off),第二条输出hello world,第三条、第四条暂停并提示(pause)。
[quote]从这里可以看出,从批处理程序调用另一个批处理程序的执行流程:先执行原批处理中的代码,当遇到调用时再执行完被调用的批处理中的所有代码,最后返回到原批处理再执行call语句之后的代码。这种执行流程,同样适用于call 调用标签(内部函数)[/quote]
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[code]echo %2
pause[/code].
再次执行hello.bat,结果:[code] world
请按任意键继续. . .[/code].
“hello”不见了,只显示了“world”,这给人一种感觉,好像%1代表了“hello”,%2代表了“world”——事实上也确实如此。
我们可以将%1~%9这九个参数看成是批处理的形参,在这个例子中,%1,%2就是形参,而“hello”、 “world”就是实参。
[quote]这种参数的传递,执行流程就是在原批处理中将实参传递到被调用批处理中的形参中。[/quote]
例如:
将hello.bat,test.bat进行如下修改。
hello.bat[code]@echo off
call test.bat 3 9
pause[/code].
test.bat[code]Set /a n=%1+%2
echo %n%
pause[/code].
运行hello.bat,结果返回12。
[quote]实参中的分隔符可以是空格、逗号、分号、等于号,“call test.bat 3 9”写成“call test.bat 3,9”、“call test.bat 3;9”、“call test.bat 3=9”都是可以的。[/quote]
3.调用一个内部函数(标签)
如果把“被调用批处理”看成是外部函数,那么标签就可以看成是内部函数。
修改hello.bat的内容:[code]@echo off
call :1 "hello"
pause
exit
:1
echo.%~1[/code].
[quote]call调用标签时冒号(:)不可以省略,和goto不同(goto跳转时,冒号可有可无)。[/quote]
4.函数调用中非实参形参对应关系的变量值的相互传递。
hello.bat[code]@echo off
Set n=1
call :1 "hello"
pause
exit
:1
echo.%~1
echo %n%[/code]代码的执行结果:[code]hello
1
请按任意键继续. . .[/code].
[quote]以上结果说明,内部函数中,变量n的值,可以在主函数中定义,在被调用函数中输出。——这种结果,同样会出现在外部函数中(一个批处理调用另一个批处理)。[/quote]
再次修改hello.bat[code]@echo off
call :1 "hello"
echo %n%
pause
exit
:1
echo.%~1
Set n=1[/code].
结果:[code]hello
1
请按任意键继续. . .[/code][quote]以上结果说明,内部函数中,变量n的值,也可以在被调用函数中定义,在主函数中输出。——这种结果,同样会出现在外部函数中(一个批处理调用另一个批处理)。[/quote]
5.嵌套调用
嵌套调用就是一个被调用的函数中还有一个调用其它函数的命令,就好像小时候玩的那工兵、班长、排长、连长、团长……,团长 call 连长,连长 call 排长,……,班长 call 工兵,然后工兵才开始干活。
修改两个批处理的内容:
hello.bat[code]@echo off
call test.bat world
echo %m%
pause&exit[/code].
test.bat[code]Echo %1
Set m=1
call :1 hello
pause&exit /b
:1
echo %1
[/code].
结果:[code]world
hello
请按任意键继续. . .
1
请按任意键继续. . .[/code].
这里,test.bat是被调用的函数,但它自身又包含一个内部子函数(:1)——这就是函数的嵌套。
[quote]可以看出虽然test.bat中有两个%1,但是它们的值并不相同,这说明父函数的形参并不等于子函数的形参。[/quote]
[color=Red]注意:这里exit /b 是用来退出子函数的,不加/b参数就会退出整个cmd.exe(区别就是,加/b父函call之后命令还会执行,不加/b父函数call之后的命令就不会执行了)。[/color]
可以把test.bat中的exit /b 替换为 exit 体会一下。
6.函数的递归调用
[url]http://bbs.bathome.net/thread-1264-1-6.html[/url]
[color=Red]这篇教程由pusofalse提供。[/color]
[color=Green]扩展阅读:[/color]
1.利用call实现变量延迟。[code]@echo off
for /l %%i in (1 1 5) do (
Set n=%%i
set /a n+=1
call echo %%n%%
)
pause[/code].
2.call和for一起使用。[code]::在文件路径前加“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%
[/code].
第二种方法的作用其实更大。但是第一种方法用的却更多。 [code]call echo %%n%%[/code]这个不错 [b]回复 [url=http://bbs.bathome.net/redirect.php?goto=findpost&pid=97755&ptid=14852]1#[/url] [i]Hello123World[/i] [/b]
总算明白%1~9的用法了 对批处理越来越佩服了 学到很多,每天都进步一点,谢谢分享。 [b] 深有体会啊!遇到变量引用时非常有用[url=http://bbs.bathome.net/redirect.php?goto=findpost&pid=97755&ptid=14852]1#[/url] [i]Hello123World[/i] [/b] 最后一例显示为:
This is a text:%1 ???{:3_53:} 批处理博大精深,学习了 @echo off
rem 用^call命令去理解%*这些常理的应用
call :x 1 10
pause&exit
:x
for /l %%i in (%1,%1,%2) do echo %%i call echo %%n%%还一定要加两层%% 为什么是要加两层%呢,是什么意思呢? 有一些行确实看不明白,希望指教一下
call echo %%n%% 这句是什么意思呢?
call echo 怎么理解?
%%n%% 又怎么理解?
谢谢 嵌套调用,有些地方又叫函数链式调用
批处理中的变量定义范围好像没的javascript那么受限制一样,全局或局部
页:
[1]