标题: [其他] 批处理中start与call的用法的区别是什么? [打印本页]
作者: LJanswer 时间: 2010-12-13 21:01 标题: 批处理中start与call的用法的区别是什么?
start与call的用法的区别?
作者: hanyeguxing 时间: 2010-12-13 21:17
call的最大特点是可以调用本批内的标签,继承父批的环境变量,返回时带着子批的环境变量,start不能。
作者: LJanswer 时间: 2010-12-13 22:16
有点抽象,能否举个例子说明一下?我接受批处理的时间不长,还只是个菜鸟。
作者: hanyeguxing 时间: 2010-12-13 22:25
- @echo off
- set a=123
- call:han 789
- echo 来自call的变量:%b%
- pause&exit
- :han
- echo 参数%1
- echo 变量a可以在这里用:%a%
- set b=456
复制代码
作者: wc726842270 时间: 2010-12-14 00:04
说实话个人认为LZ还是先了解一下START。CALL这两个命令的基础比较好,至于区别即使给你答案,也会事半功倍
如果想暂时的了解一下参考下http://www.bathome.net/viewthrea ... amp;highlight=start
另外论谈的搜索功能也是非常的强大,有什么不明白的地方,这应该是首选
作者: LJanswer 时间: 2010-12-14 11:17
通过4楼的例子,还有5楼提供的参考,我对start与call的区别有了进一步的了解,谢了!
作者: applba 时间: 2011-5-23 18:43
请问一个批处理a.cmd可以直接调用另一个批处理b.cmd内部的标签:sub吗?
作者: CrLf 时间: 2011-5-23 18:56
7# applba
据我所知,直接调用的好像没有
作者: applba 时间: 2011-5-23 19:20
比如我把很多常用的子过程或者函数放到一个批处理里面。
然后我这样调用 call b.cmd "sub 123"
sub是子过程,123是参数
作者: plp626 时间: 2011-5-23 19:30
比如说子过程库(标签以/开头)文件为sos.cmd
添加“文件头”:- @(
- if "%~1"=="/plp" (
- call:%2 %*
- )else call:%*
- goto:eof
- )
复制代码
然后 sos/子过程标签 参数列表
我的库函数就这么搞的。。。当然不一定必须这么搞,,只是个思路。。。
作者: qzwqzw 时间: 2011-5-23 22:06
10# plp626
怎么觉得楼上的用法如此怪异
原来是@()的在作怪
在call 不支持直接调用标签的时候
那时是MS-DOS为王的时代
就已经有了标准调用内部或外部的标签的做法
基本上采用下面的形式
1.简单的基本用法
@echo off
if [%1]==[$] goto %2
:sub1
rem some code
goto :end
:end
调用的时候采用
call %0 $ sub1
外部调用采用
call lib.bat $ sub1
2.在需要传递参数的时候
@echo off
if [%1]==[] goto :end
shift
shift
goto %0
:function1
echo %1+%2+%3
rem some code
goto :end
:end
调用的时候采用
call %0 $ func1 arg1 arg2 arg3
外部调用采用
call lib.bat $ func1 arg1 arg2 arg3
3.在需要返回结果值的时候
@echo off
if [%1]==[] goto :end
shift
shift
goto %0
:func2
rem some code
set _ret=%2-%1-%3
goto :end
:end
调用的时候仍然采用
call %0 $ func2 arg1 arg2 arg3
外部调用也是采用
call lib.bat $ func2 arg1 arg2 arg3
只不过多了使用 %_ret% 引用返回结果的语句罢了
4.到了WinNT时代
cmd功能强了限制少了
Call可以直接调用内部标签了
shift移位可以保留%0了
命令行参数也可以增强扩展了
标签名不再限制8个字符长度了
不过基本思想变化不大
@echo off
if [%1]==[$] shift/1&shift/1&goto %2
:function
rem some code
set _ret=%2-%1-%3
goto :end
:end
调用的时候仍然采用
call %0 $ func2 arg1 arg2 arg3
外部调用也是采用
call lib.bat $ func2 arg1 arg2 arg3
5.当然对于要求不严格的场合
用if not [%1]==[] goto %1跳转标签也是可以的
作者: plp626 时间: 2011-5-23 22:13
本帖最后由 plp626 于 2011-5-23 22:18 编辑
11# qzwqzw
%1 %2 。。。
这样最多也就支持9个,如果shift要goto费时。。。而且在预处理时会把参数分隔符比如等号,逗号,分毫给吃了。。
为了参数原样传递给子过程我才用了%*,至于其他的分解参数是子过程自己的事。。。
所以你看我有个当第一个参数为/plp的时候,对参数2作为标签。。。。否则默认把第一个参数作为标签。。。
为了最大程度传递参数情况下保持代码简洁又可读性好些。。。
作者: plp626 时间: 2011-5-23 22:23
11# qzwqzw
这个思路后再做些工作——就是统一接口。。。。
作者: qzwqzw 时间: 2011-5-24 08:51
12# plp626
call存在对"^"的错误处理
而且使用 call :label 会丢失掉%0
而在 :label 中可能会使用到这个 %0
比如遇到错误时的抛出处理
或者对自身文本内容的操作
所以在此之前需要 set program_name=%0
至于%1 %2 %3
即使goto到:label
也仍然可以使用%*分析命令行
而call:%2 %*会把/plp也传进去
这未必是你想看到的吧?
“如果shift要goto费时”
没看懂
下面是采用:标志子过程调用的处理方法
调用采用 call lib.cmd :sub1 arg1 arg2- @echo off
- for /f "tokens=2 delims=:" %%s in ("_%1") do shift/1&goto %%s
-
- :sub1
- echo %0-%1-%2-%3.
- echo %*.
- pause
- goto :eof
复制代码
下面是采用.标志子过程调用的处理方法
调用采用 call lib.cmd sub1. arg1 arg2- @echo off
- if [%~sn1.]==[%~s1] shift/1&goto :%~sn1
-
- :sub1
- echo %0-%1-%2-%3.
- echo %*.
- pause
- goto :eof
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |