我想设置一个变量,例如%p%
然后在CMD的同一行中使用它。
e.g:
set p=notepad.exe&%p%
这不起作用。但%p%
设置为下一行。因此,如果我第二次执行此行,则可以正常工作。
如何在同一行中使用%p%
?
答案 0 :(得分:10)
执行批处理文件时,首先解析每行或每行(括号中的行),然后执行。在解析期间,对变量的读取操作将替换为执行命令之前变量内的值。因此,如果在行/块中更改了变量值,则无法检索此更改的值,因为解析器在更改之前已使用变量中的值删除了读取操作。
所以,你的代码
set p=notepad.exe&%p%
被解析并转换为
set p=notepad.exe&
其中获取%p%
的读取操作已替换为变量中的值(该示例假定变量为空)。然后执行此解析行。
为什么它第二次运作?因为在之前的运行中已经设置了变量,并且如果它尚未被重置,当解析器在第二次运行中执行替换时,变量包含要在行中替换的值。
要在执行行为之前看到这是一个解析,您可以将行更改为
set p=notepad.exe&set p
即设置变量并转储环境内容(以p开头的变量),您将看到该变量已设置为notepad.exe
。由于此行不包含对变量的任何读取操作,因此一切都按预期工作。
如何解决您的问题?有一些选择
延迟扩展
当启用延迟扩展时,可以在需要时将变量读取的语法从%var%
更改为!var!
,向解析器指示读取操作的替换需要延迟到命令执行
setlocal enabledelayedexpansion
set p=notepad.exe&!p!
如果使用/v:on
cmd /v:on /c "set p=notepad.exe&!p!"
强制对命令进行第二次解析
这使用call
命令在行
set p=notepad.exe&call %%p%%
第一个默认解析用文字%%p%%
替换文字%p%
(%%
是转义的百分号)而不进行任何变量替换,以及call
命令执行后,该行再次被解析,因此文字%p%
被解释为变量读取并被变量中的值替换
用什么?这取决于。延迟扩展解决方案具有更好的执行时间,call
解决方案(call
命令可以执行更多工作),但是当启用延迟扩展时,数据中包含的感叹号字符(!
)成为问题需要妥善处理。