Board logo

标题: [原创] 批处理中的call与start的个人学习心得 [打印本页]

作者: taojunyi    时间: 2009-1-24 13:10     标题: 批处理中的call与start的个人学习心得

1、call用来调用执行另一个bat或者cmd文件(当然也可执行其它格式的可执行文件),
start用来调用执行其他格式的可执行文件(exe,com,vbs...)。
2、call具有goto的功能,在程序中实现灵活跳转,而start则不具有这种功能。以下
是我试验用的程序段。
:begin
@echo off
set /a a=%random%%%10
echo %a%
pause>nul
if %a% geq 5 (call :run2) else call :run1
:run1
echo 111111111
call :ex
:run2
echo 222222222
:ex
call :begin
3、call具有传递变量到外部的批处理上并能回传,而start则不具备回传功能(可以将call换成start试
试)
=========
::b.bat如下:
@echo off
for /l %%i in (1,1,3) do call b.bat %%i
pause
==============
::b.bat如下:
@echo off
echo number is %1


以上是我的学习心得,我希望大家也把心得写成小文章, 发表在上面,一起提高

[ 本帖最后由 taojunyi 于 2009-3-3 20:21 编辑 ]
作者: yslyxqysl    时间: 2009-1-24 13:39

start用来调用执行其他格式的可执行文件

start用来执行任何格式的文件。
call具有传递变量到外部的批处理上,而start则不具备(可以将call换成start试试)

start可以做到,只是你没有pause住。
call具有goto的功能,在程序中实现灵活跳转

call和goto的区别在于call可以用goto :eof回来,而goto则一去不复返。
作者: defanive    时间: 2009-1-24 13:48

start是调用系统默认的打开方式执行一个文件,是在一个新的进程里面执行
作者: taojunyi    时间: 2009-1-24 14:44

2楼的兄弟,你能举个例子:用start把一个批文件里的变量值传到另一个批处理中??我觉的start仅仅用来启动文件。
call和goto的区别除了您说的,写法上也有区别的
作者: defanive    时间: 2009-1-24 15:02

从你的例子里面,你可以在b.bat最后加个pause
然后再执行a.bat,事实上都是可以的。。
作者: defanive    时间: 2009-1-24 15:21

main.bat
  1. @echo off
  2. set a=1
  3. pause
  4. echo call child.bat
  5. call child.bat
  6. echo end call
  7. pause
  8. echo %b%
  9. pause
复制代码

child.bat
  1. @echo off
  2. echo %a%
  3. set b=20
  4. pause
复制代码


注意,这个实验中,main.bat定义了变量a为1,在child.bat中定义了变量b为1
main.bat首先将call child.bat,然后child.bat将echo %a%,现在能正常显示1。call完之后,main.bat将echo %b%,也能正常显示20

如果将call改为start,待child.bat执行完再关闭之后,main.bat继续echo %b%,将无法显示变量b的值

call的时候,他们拥有同一个壳cmd.exe,在同一个进程当中,所以他们的变量是互通的

start的时候,他们拥有两个壳cmd.exe,但在不同的进程当中,而由于这是他们的壳都是cmd.exe,所以child.bat可以看成是main.bat的子进程,子进程可以读取父进程中的变量,但不能赋予父进程变量的值。而当start的程序不同的壳的时候,他们就不是父子进程关系。

我是这样理解的,有不同意见以砖拍之。。。
作者: taojunyi    时间: 2009-1-24 15:34

1、是的,start是一个新的进程中执行的,也是能传递变量值到外部批处理上。
2、另一点call和goto的区别,二楼的兄弟说的不对:“call和goto的区别在于call可以用goto :eof回来”。我的理解是call之后,就执行到指定标签上并往后执行到未尾,然后再回到call句之后,是自然回来的,而非goto:eof回来的。goto:eof的:eof是默认的标签,不用定义,此句是直到最后并结束批文件。
@echo off
set /a a=%random%%%10
echo %a%
pause>nul
if %a% geq 5 (call :run2) else call :run1
goto :eof
:run1
echo 111111111
goto :ex
pause>nul
:run2
echo 222222222
:ex
pause>nul
作者: wxcute    时间: 2009-1-24 15:49

GOTO :EOF
通俗解释为结束当前批处理。

因为 CMD 执行到 CALL ABLE <参数> 时会将被调用标签下所有内容当做一个批处理文件来执行。
所以在这个新的批处理文件中是可以用 GOTO :EOF 来结束的。
就算标签内 GOTO :EOF 语句下面还有其他语句也不会执行。
作者: defanive    时间: 2009-1-24 15:55

goto :eof在父批中是退出批处理,在call(或者说子批)是退出当前批,也就是退出call这一线程(CMD是单线程程序,执行完一个线程才能执行下一个线程),那么退出了这一个线程就回到了调用这一个线程的地方,继续执行。。。

正应为是线程,处在同一个进程和同一个壳中,变量可以共用。。。
作者: taojunyi    时间: 2009-1-24 15:55

6楼的兄弟理解透彻,我向您学习
对于start,概况二句话:“不同进程不能传值”,“相同进程单向传值,老子传儿子,非儿子传老子“
对于call,“同一进程,变量互通”
作者: taojunyi    时间: 2009-1-24 16:07

对于start:“不同类型进程不能传值”,“相同类型进程单向传值,父传子“
对于call,“同一进程,变量互通”
作者: taojunyi    时间: 2009-1-24 16:34

今日有所收获,谢谢大家,对于call和goto:eof,改了下之后更简捷
@echo off
set /a a=%random%%%10
echo %a%
pause
if %a% geq 5 (call :run2) else call :run1
goto :eof
:run1
echo 小于5
pause
goto :eof
:run2
echo 大于等于5
pause
作者: hunrybecky    时间: 2009-2-26 22:59

具体可以参考
http://xbdsoft.kmip.net/article/study/28.htm
一是调用范围不同:CALL主要用来进行批处理的内部调用如CALLEND和一些DOS命令的调用如CALL SET TEST=2,但也可以调用其他可执行文件,而START则不能进行内部调用,但其可以执行基本上所有的外部程序,还可以执行SHELL,如打开文件夹START "" "%WINDIR%",安装网络打印机START "" "\\IP\Printer",同时需要注意有无START调用外部程序的区别;

      二是调用方式不同:CALL实际上调用,所以在CALL另一个批处理时是在同一窗体进程里执行,而START是执行,所以在执行另外一个批处理时是在不同的窗体进程里执行,也就是说在新的进程里执行,虽然START可以加入B参数,但其结果却完全不同.如我们使用CALL SET TEST=2和START /B SET TEST=2看似执行的结果相同,但是我们发现后者有两个进程,而且在窗体里要执行两次EXIT才能退出,所以当我们使用START来执行一个批处理后最好在被调用的批处理中也加一个EXIT,否则无法退出被调用的批处理的DOS窗体,但是使用CALL调用时如果在被调用的批处理中存在EXIT则会直接结束原始和别调用的批处理程序,这是一个非常严重的问题,建议在被调用的程序中使用goto:eof来取代EXIT;.

     三是调用结果不同:CALL调用不仅可以把参数或变量传给被调用的批处理,而且被调用的批处理也可以设置参数或变量以便回传,而START只能把参数或变量传给被调用的批处理,却不能回传参数或变量,这一点实际上是第二点的延伸.至于此我们还必须注意使用CALL调用其他批处理中我们使用GOTO的时候建议使用不同的节来跳转,否则可能跳转到原批处理中而不能完整的执行被调用的批处理.
作者: epissq1    时间: 2009-3-4 09:38

:begin
@echo off
set /a a=%random%%%10
echo %a%
pause>nul
if %a% geq 5 (call :run2) else call :run1
:run1
echo 111111111
call :ex
:run2
echo 222222222
:ex
call :begin



不知道这个批处理能不能无循环的运行下去啊
作者: qxhonker    时间: 2009-3-5 14:37

楼上的只要不ctrl+c就会一直循环的吧
作者: fsh6666    时间: 2009-3-7 13:47

不错    学习中     !!!!!!!!!!!
作者: 5566ljlj    时间: 2009-11-6 16:46

个人觉得还是前面13楼概括的挺好的
作者: faladi    时间: 2012-12-3 19:58

有没有讲解start各个参数的教程,有哪位同胞知道或者自己弄透了的,能否指点一下,谢谢咯!
作者: wangx    时间: 2013-9-16 15:49

具体可以参考

一是调用范围不同:CALL主要用来进行批处理的内部调用如CALLEND和一些DOS命令的调用如CAL ...
hunrybecky 发表于 2009-2-26 22:59

归纳的很全面呢
作者: hzcxdgioa    时间: 2013-9-17 10:08

回复 13# hunrybecky


   start /b /wait这样行不行?
作者: 853122    时间: 2013-9-30 00:12

学习
作者: ai20110304    时间: 2018-8-30 16:38

call回传和设置同一变量,start开启新进程环境
作者: 小程936    时间: 2019-1-1 16:59

start用来执行任何格式的文件。

start可以做到,只是你没有pause住。

call和goto的区别在于call可以 ...
yslyxqysl 发表于 2009-1-24 13:39



start /w 执行第三方程序的效果特别好(等待程序结束后继续)
为什么要用goto :eof
exit /b 难道不是秒杀吗?
不论是代码长度,易记程度,执行速度,exit /b都完胜。
https://docs.microsoft.com/zh-cn ... 0/cc772743(v=ws.10)
作者: Batcher    时间: 2019-1-1 21:02

回复 23# 小程936


    执行速度方面,有什么数据做过对比吗,能否给大家分享一下?




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2