当一个 CMD 脚本从函数内部运行另一个脚本时产生的奇怪效果

当一个 CMD 脚本从函数内部运行另一个脚本时产生的奇怪效果

当一个 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.cmdshow.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 将不同批处理文件中的变量完全分开,这将避免两个脚本使用相同变量名时出现的任何潜在问题。

相关内容