当一个 BAT 或 CMD 脚本运行另一个脚本(不带call
)时,应该不是返回,对吧?
有时确实如此!
而且它在另一个脚本中搜索相同的函数标签?!?
例如:(您认为输出结果会是什么?)
@echo off
call :a
call :b
show 5
echo 6
goto :EOF
:a
show 1
echo 2
goto :EOF
:b
if 1==1 show 3
echo 4
goto :EOF
使用这个show.cmd
或show.bat
:
@echo off
echo %1
goto :EOF
:a
echo %1 a
goto :EOF
输出为(在Win10-22H2和Win7中测试)
1 a
3
5
我曾预料到
1
这意味着:如果另一个脚本从函数内部运行,它只会跳过该函数的其余部分,然后执行其余部分。它会尝试在另一个脚本中查找同名的函数。后者可以通过在前面添加 来防止if 1==1
。
这些效果是缺陷吗?还是我可以依赖的功能?
答案1
这是 CMD 的已知行为。从ss64 的 CALL 页面:
如果您执行第二个批处理文件而不使用 CALL,您可能会遇到一些错误行为:如果两个批处理文件都包含同名的标签,并且您之前已使用 CALL 跳转到第一个脚本中的该标签,则您会发现第二个脚本的执行从相同的标签开始。即使第二个标签不存在,这仍然会引发错误“找不到批次标签”。始终使用 CALL 可以避免此错误。
您可以在脚本中使用CALL show.cmd 1
而不是 来修复show 1
。ss64 还提供了有关保持子例程和函数连贯性的更多好建议:
在许多情况下,您还需要使用 SETLOCAL 和 ENDLOCAL 将不同批处理文件中的变量完全分开,这将避免两个脚本使用相同变量名时出现的任何潜在问题。