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