Board logo

标题: [文件操作] 两个批处理之间参数的传递与变量本地化 [打印本页]

作者: ibm    时间: 2009-4-24 21:29     标题: 两个批处理之间参数的传递与变量本地化

现有File1.bat和File2.bat两个批文件,

File1.bat中的代码:
  1. @echo off
  2. rem XXXXXXXXXXXXXXXX File1 XXXXXXXXXXXXXXXX
  3. call File2 100 TestVar
  4. echo.
  5. echo XXXXX最后的输出XXXXX:TestVar=[%TestVar%]
  6. echo.
  7. echo.
  8. echo End&&pause >nul
  9. exit /b
复制代码


File2.bat中的代码:
  1. rem XXXXXXXXXXXXXXXX File2 XXXXXXXXXXXXXXXX
  2. :file2
  3. SETLOCAL ENABLEDELAYEDEXPANSION
  4. set /a "testA=%~1"
  5. set "testB=%~2"
  6. set /a testA+=100
  7. SETLOCAL DISABLEDELAYEDEXPANSION
  8. endlocal
  9. set "%testB%=%testA%"
  10. echo 过程(File2):[testA=%testA%][testB=%testB%][TestVar=%TestVar%]
  11. set "testA="
  12. set "testB="
  13. goto :eof
复制代码


经过测试,当File2.bat中停用『SETLOCAL ENABLEDELAYEDEXPANSION 』,其结果[TestVar]就可以正常输入,反之不可以,
问题是怎么即使用『SETLOCAL ENABLEDELAYEDEXPANSION 』,又能够得到[TestVar]的值?
研究这个的目的,是想把File2.bat制作成类似C++中的函数,以方便调用,并且能到得到返回值。
作者: 随风    时间: 2009-4-24 21:42

  1. @echo off
  2. call File2 100 TestVar
  3. echo.
  4. echo XXXXX最后的输出XXXXX:TestVar=[%TestVar%]
  5. echo.
  6. echo.
  7. echo End&&pause
  8. exit /b
复制代码
File2
  1. @echo off
  2. :file2
  3. SETLOCAL
  4. set /a "testA=%~1"
  5. set /a testA+=100
  6. echo %~2=%testA%
  7. endlocal&set %~2=%testA%&goto :eof
复制代码

作者: ibm    时间: 2009-4-24 22:09     标题: 回复 2楼 的帖子

版主,你没明白我的意思,我要保留『SETLOCAL ENABLEDELAYEDEXPANSION 』和『SETLOCAL DISABLEDELAYEDEXPANSION』,虽然它们在这个例子中可以省略,我只是拿这个简单的代码为例而已。
作者: 随风    时间: 2009-4-25 08:25

  1. @echo off
  2. rem XXXXXXXXXXXXXXXX File1 XXXXXXXXXXXXXXXX
  3. call File2 100 TestVar
  4. echo.
  5. echo XXXXX最后的输出XXXXX:TestVar=[%TestVar%]
  6. echo.
  7. echo.
  8. echo End&&pause >nul
  9. exit /b
复制代码
  1. rem XXXXXXXXXXXXXXXX File2 XXXXXXXXXXXXXXXX
  2. :file2
  3. SETLOCAL ENABLEDELAYEDEXPANSION
  4. set /a "testA=%~1"
  5. set "testB=%~2"
  6. set /a testA+=100
  7. SETLOCAL DISABLEDELAYEDEXPANSION
  8. endlocal
  9. set "%testB%=%testA%"
  10. echo 过程(File2):[testA=%testA%][testB=%testB%][TestVar=%TestVar%]
  11. set "testA="
  12. set "testB="
  13. endlocal&set %~2=%TestVar%&goto :eof
复制代码

作者: ibm    时间: 2009-4-25 19:49     标题: 回复 4楼 的帖子

研究了好一会儿你的这段代码,在《File2》的最后一行,有%TestVar%这个变量,并没有任何一处给它定义和赋值,它却能%~2=%TestVar%,而且居然结果正确,不解!
我的初衷,%TestVar%这个变量,是在《File1》中用来接收《File2》的返回值时才用到的变量。
作者: Batcher    时间: 2009-4-25 20:49     标题: 回复 5楼 的帖子

你把@echo off删除,就知道变量%TestVar%是啥时候被赋值的了。
作者: ibm    时间: 2009-4-25 21:23     标题: 回复 6楼 的帖子

我的意思是TestVar这个字符串是未知的,是由File2传递进来了,
如果File1中的的批调用改为: call File2 100 Variable ,
岂不是还是更改4楼的File2中最后一行的代码 set %~2=%TestVar% ?

[ 本帖最后由 ibm 于 2009-4-25 21:25 编辑 ]
作者: 随风    时间: 2009-4-25 21:47     标题: 回复 7楼 的帖子

估计等我回答了你的这个问题,你又说不是你要的了。
不过这个我就不会了,应该作不到吧。。
下次提问请一次性把问题描述清楚。。。。。。。。。。。。。
作者: ibm    时间: 2009-4-25 22:30     标题: 回复 8楼 的帖子

由于是两个批的调用与参数传递,供述起来就会有难度,所以没有在群里面讨教,而选择在这里发帖,
endlocal具有“结束批处理文件中环境改动的本地化操作”的功能,但应用上似乎有点问题,
期待问题的解决
作者: Batcher    时间: 2009-4-25 23:08     标题: 回复 9楼 的帖子

首先,我们来看看英文版的帮助文档是怎么写的,这样或许好些。
C:\Test>endlocal /?
Ends localization of environment changes in a batch file.
Environment changes made after ENDLOCAL has been issued are
not local to the batch file; the previous settings are not
restored on termination of the batch file.

ENDLOCAL

If Command Extensions are enabled ENDLOCAL changes as follows:

If the corresponding SETLOCAL enable or disabled command extensions
using the new ENABLEEXTENSIONS or DISABLEEXTENSIONS options, then
after the ENDLOCAL, the enabled/disabled state of command extensions
will be restored to what it was prior to the matching SETLOCAL
command execution.


其次,需要明确的一点是,如果在File2.bat中使用了SETLOCAL ENABLEDELAYEDEXPANSION,即使你没有显式添加endlocal,在File2.bat结束时仍然会执行endlocal。

换句话说,如果在被调批处理File2.bat中启用了变量延迟扩展,传进来的参数TestVar只在File2.bat中有效,File2.bat结束时,由于会执行endlocal,因此TestVar会被销毁,主调批处理File1.bat自然无法得到它的值了。

[ 本帖最后由 Batcher 于 2009-4-25 23:37 编辑 ]
作者: batman    时间: 2009-4-25 23:14

用得着这么复杂吗?如下就可实现:
  1. @echo off
  2. rem t.bat
  3. call text.bat 1 2
  4. echo %a% %b%&pause>nul
复制代码
  1. @echo off
  2. rem test.bat
  3. set /a a=%1,a+=1,b=%2,b+=2
复制代码

作者: Batcher    时间: 2009-4-25 23:20     标题: 回复 11楼 的帖子

没看清楼主的意思吧?
^_^
作者: batman    时间: 2009-4-25 23:25

回楼上,的确是的,也同意你10楼的描述。。。。
作者: netbenton    时间: 2009-4-26 00:01     标题: re 7楼

使用
SETLOCAL DISABLEDELAYEDEXPANSION
后,会把以前的环境压栈,这中间是不能改变和增加以前的变量环境的
直到
endlocal&set %~2=%TestVar%  或 退出当前程序
才把环境恢到以前。

既然退出当前程序时也会被恢复到以前的状态,变量新的值就不能传回给主程序了。

可是在执行
endlocal  语句
之后已经回到了以前的环境,此句之后发生的变化是可以传回给主程序的。

所可以这样:
endlocal&set %~2=%TestVar%      //经预处理后为:endlocal&set Testvar=[变量值]
使变量值在endlocal执行之前经预处理,已经扩展了,就算恢复到以前的环境对它已经影响不到了
相当于前面的工作,只收获了Testvar=[变量值]

因为SETLOCAL DISABLEDELAYEDEXPANSION是保护了以前的环境的,
所以在这中间的变量名不管你用什么,对主程序都不会有影响,
变量:%TestVar% 改用其它的,如:%kkk%
set kkk=!TestVar!

endlocal&set %~2=%kkk%
一样可以把值通过%2给出的变量传回去。

[ 本帖最后由 netbenton 于 2009-4-26 00:05 编辑 ]
作者: Batcher    时间: 2009-4-26 00:15     标题: 回复 14楼 的帖子

估计楼主的意思是在File2.bat中根本就不允许使用TestVar这个变量,它完全是由File1.bat传过来的。
作者: ibm    时间: 2009-4-27 18:52

回复 15楼 的帖子
楼上说的没错,File2.bat中不能用到TestVar,因为在设计File2.bat时,还不知道使用File1.bat的人会传递进来什么变量。



回复 9楼 的帖子
在File2.bat结束前加入endlocal,为什么最后TestVar还是会被销毁?




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