如何设置变量,然后在命令提示符的同一行中使用它

A.D*_*esh 5 cmd batch-file

我想设置一个变量%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命令执行更多工作),但是当启用延迟扩展时!,数据中包含的感叹号字符()成为需要正确处理的问题.

  • +1,注意CALL非常慢.因此,如果性能是一个问题,那么延迟扩展优于CALL (3认同)