[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创] 批处理中的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 编辑 ]
1

评分人数

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

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

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

call和goto的区别在于call可以用goto :eof回来,而goto则一去不复返。

TOP

start是调用系统默认的打开方式执行一个文件,是在一个新的进程里面执行

TOP

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

TOP

从你的例子里面,你可以在b.bat最后加个pause
然后再执行a.bat,事实上都是可以的。。

TOP

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的程序不同的壳的时候,他们就不是父子进程关系。

我是这样理解的,有不同意见以砖拍之。。。
1

评分人数

    • pumahxh: 分析透彻,感谢分享!PB + 5

TOP

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

TOP

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

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

TOP

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

正应为是线程,处在同一个进程和同一个壳中,变量可以共用。。。

TOP

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

TOP

对于start:“不同类型进程不能传值”,“相同类型进程单向传值,父传子“
对于call,“同一进程,变量互通”

TOP

今日有所收获,谢谢大家,对于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

TOP

具体可以参考
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的时候建议使用不同的节来跳转,否则可能跳转到原批处理中而不能完整的执行被调用的批处理.
1

评分人数

TOP

: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



不知道这个批处理能不能无循环的运行下去啊

TOP

楼上的只要不ctrl+c就会一直循环的吧

TOP

返回列表