综合列表 - 在批处理文件中运行代码与直接在控制台中输入代码

Posted

技术标签:

【中文标题】综合列表 - 在批处理文件中运行代码与直接在控制台中输入代码【英文标题】:Comprehensive list - Running code in batch file vs. entering code directly into console 【发布时间】:2017-06-14 13:29:23 【问题描述】:

我正在寻找在 windows cmd 窗口中运行完全相同的代码(手动逐行输入)与编写批处理文件并运行它之间的差异的综合列表。

我不可能是第一个提出这个问题的人,但是 Google 和多次堆栈溢出搜索都没有返回我想要的结果。我主要比较 .bat & .cmd 这样的一个,或者 specific questions 关于 a single issue。我知道还有其他差异,例如我刚刚发现

set "filename=foo"
set "optional_postfix="
set "filetype=.cpp"

set completename=%filename%%optional_postfix%%filetype%
echo %completename%
PAUSE

表现不同。

我想了解所有差异,因为在尝试了半小时应该工作的东西之后发现它们并在之后发现差异非常烦人。

如果这里已经存在这样的列表,请不要对我投反对票,我实际上花时间寻找它 - 至少对我来说 - 如何找到它并不明显。其他人可能有同样的问题,所以请将其标记为重复。

【问题讨论】:

首先参考这个帖子:How does the Windows Command Interpreter (CMD.EXE) parse scripts? 快速回复:cmd 中的某些命令不起作用:gotoshiftsetlocalendlocalcall :Label; ; set /A 将(最后)结果写入cmd 中的控制台,但不在批处理文件中;没有argument expansion;未定义的环境变量在批处理文件中扩展为空字符串,但在cmd 中进行维护; %% 在批处理文件中变成文字 %,但在 cmd 中没有;这就是为什么你必须在批处理文件中声明for %%I in ...,但在cmd 中声明for %I in ...;并且一些命令可能会或可能不会重置ErrorLevel... @aschipfl:感谢您的链接,这似乎是一个好的开始。难怪我没有通过搜索找到它,我永远不会仅仅通过阅读标题就猜到它包含我正在寻找的内容。 虽然主题不同,但您可以在this answer 的批处理文件中查看这些差异的列表以及如何使用此类命令行命令not 的完整示例 【参考方案1】:

无论是在cmd 还是在批处理文件上下文中执行命令,都存在许多差异,但所有这些都指的是cmd-internal 命令或功能。

以下命令在cmd 上下文中执行时不执行任何操作(它们不会产生任何输出并且不会影响ErrorLevel):

goto shift setlocal(要在cmd 中启用/禁用命令扩展或延迟扩展,请改用cmd /E:ON|OFF /V:ON|OFF 调用实例) endlocal

标签(如:Label)不能在cmd 中使用,它们会被忽略。因此,call :Label 也不能使用(如果这样做,会出现错误消息,ErrorLevel 会设置为 1)。

cmd 中当然没有argument expansion,因为不可能提供参数。因此,像%1 这样的字符串会按原样返回(尝试使用echo %1)。这允许在cmd 中定义以数字开头的变量名,这在批处理文件中是不可能的(实际上你可以定义它们,但你不能%-展开它们;在批处理文件中试试这个:@987654345 @,然后是set 1;您将得到输出123=abc;但尝试执行echo %123% 将导致输出23,因为%1 被识别为参数引用(假设没有提供参数)) .

未定义的环境变量不会在cmd 中扩展(替换),但它们会按字面意思进行维护(执行set "VAR="echo %VAR%,所以你会得到%VAR%)。然而,在批处理文件中,它们被扩展为空字符串。请注意,在批处理文件中而不是在cmd 中,两个连续的百分号%% 被一个% 替换。同样在批处理文件中但不在cmd 中,单个% 符号将被删除。

关于百分比扩展(参数引用和环境变量)的更多信息可以在这个线程中找到:How does the Windows Command Interpreter (CMD.EXE) parse scripts?

set /A 命令的行为有所不同:在cmd 中,它返回控制台上表达式的(最后一个)结果(没有尾随换行符),但在批处理文件中它不返回任何内容。

for 命令在批处理文件中要求其循环变量引用前面有两个百分号(如for %%I in ...),但在cmd 中只有一个百分号(如for %I in ...)。这是批处理文件和cmd 中不同百分比扩展处理的结果。

最后,一些命令在成功时不会重置ErrorLevel,除非它们在带有.cmd 扩展名的批处理文件中使用。它们是:

assoc dpath ftype path prompt set

有关重置ErrorLevel 的更多信息可以在这篇文章中找到:Which cmd.exe internal commands clear the ERRORLEVEL to 0 upon success?

【讨论】:

以上是关于综合列表 - 在批处理文件中运行代码与直接在控制台中输入代码的主要内容,如果未能解决你的问题,请参考以下文章

.bat如何才能后台运行

性能优化 | JVM与性能优化知识点综合整理

make--变量与函数的综合示例 自动生成依赖关系

史上最详细JVM与性能优化知识点综合整理

第10课 - 变量与函数的综合示例

在Windows批处理中运行命令时管道Unity CLI编译日志文件