Batch file IF块内变量中的括号
在我的一个脚本中,我需要在Batch file IF块内变量中的括号,batch-file,parentheses,Batch File,Parentheses,在我的一个脚本中,我需要在IF语句中使用包含括号的变量,但字符串缺少一个右括号,或者脚本过早退出,此时*出乎意料(实际上不是星号),具体取决于场景 示例 @echo off SET path=%programFiles(x86)% echo Perfect output: %path% IF NOT "%path%" == "" ( REM Variable is defined echo Broken output: %path% ) pause >nul 输
IF
语句中使用包含括号的变量,但字符串缺少一个右括号,或者脚本过早退出,此时*出乎意料(实际上不是星号),具体取决于场景
示例
@echo off
SET path=%programFiles(x86)%
echo Perfect output: %path%
IF NOT "%path%" == "" (
REM Variable is defined
echo Broken output: %path%
)
pause >nul
输出
Perfect output: C:\Program Files (x86)
Broken output: C:\Program Files (x86
我认为/知道这是因为它认为C:\ProgramFiles(x86)
中的右括号是IF
语句的结尾,它在echo
完成之前退出
有没有简单的方法来解决这个问题?最好不要诉诸法律
单行IF
语句,因为我需要在其中运行多行代码
大量的GOTO
s,因为它不实用
setlocalenabledelayedexpansion
并使用!路径
而不是%path%
,因为我记得在某个地方读到,该方法在OSs中并不一致
如果没有,我会乐意接受最可靠的解决方案,不管它是什么
(这个场景不值得讨论。这只是一个精致、集中的问题示例。结构应该是这样的,就像我的实际脚本中一样,因为我不想讨论的原因。这不符合重点,只会混淆事情,分散对实际问题的注意力。)如果我读错了,请原谅,但“不是”这个词不是吗导致控件进入括号中的if并运行中断的输出
那么:
@echo off
echo Perfect output: %programFiles(x86)%
IF NOT "%programFiles(x86^)%" == "" (
REM Variable is defined
echo Broken output: %programFiles(x86)%
)
pause >nul
?echo
语句中解析变量的)
过早关闭IF
块
通常,您可以通过使用^)
转义)
来解决这个问题,但不能修改环境变量以解析为C:\Program Files(x86^)
可以通过在变量周围加引号来防止此问题
作为一个简单的例子:
> SET bad=a)b
> IF 1 == 1 ( ECHO %bad% )
b was unexpected at this time.
> IF 1 == 1 ( ECHO "%bad%" )
"a)b"
首先-您不应该将PATH变量用于自己的用途。它是一个保留的环境变量。将其用于您自己的目的可能会破坏您的脚本 最简单的解决方案实际上是使用延迟扩展。只要您的平台使用CMD.EXE,您就可以访问延迟扩展 但有一种相对简单的方法可以让它在不延迟扩张的情况下运行。你可以用引号。在解析命令时,引号作为FOR变量的名称在解析时存在。它在执行时间之前扩展为零
@echo off
SET mypath=%programFiles(x86)%
echo Perfect output: %mypath%
IF NOT "%mypath%" == "" (
REM Variable is defined
for %%^" in ("") do echo fixed output: %%~"%mypath%%%~"
)
pause >nul
编辑-何时使用延迟扩展:回复评论
Perfect output: C:\Program Files (x86)
Broken output: C:\Program Files (x86
我通常只在需要的时候(或者更准确地说,在有利的时候)使用延迟扩展。也就是说,我通常发现它在批处理代码的某些部分是有利的
主要优势
- 在代码块内查看对块内变量的更改
- 取消引用变量名称时。如果变量名作为参数传入,则可以通过延迟扩展获取变量值:
echo!%1!代码>
- 当使用变量作为参数来搜索和替换或子字符串操作时:
echo!变量:%search%=%replace%代码>,
回声!变量:%start%,%len%代码>
- 每当我需要扩展值时,不必担心其中的特殊字符需要转义或引用:
set“var=A&B”&echo!瓦尔代码>
- 包含
的变量的任意值如果启用延迟扩展,则扩展时其值中的代码>将被损坏。我经常在FOR循环中打开和关闭延迟扩展,以解决问题
- 它不适合执行“宏”(执行包含在变量值中的代码),因为命令解析的许多重要阶段都发生在延迟扩展之前。通过延迟扩展执行的“宏”无法使用许多批处理功能
- 我的建议是:
if (condition_TRUE) goto goodbye_parenthesis_BEGIN
goto goodbye_parenthesis_END ----- line when previous condition is FALSE ----
:goodbye_parenthesis_BEGIN ----- line when previous condition is TRUE ----
...
variable treatment
...
:goodbye_parenthesis_END
正如其他人已经指出的,未转义和未加引号的右括号
)
无意中结束了带括号的if
块
除了转义、引号和“消失引号”之外,还有以下其他选项:
@echo关闭
设置“路径=%ProgramFiles(x86)%”
回声完美输出:%PATH%
如果不是“%PATH%”,则为(
定义了rem变量
对于(“%PATH%”)中的%%P,是否回显未中断的输出:%%~P
)
暂停>nul
%
-符号:
@echo关闭
设置“路径=%ProgramFiles(x86)%”
回声完美输出:%PATH%
如果不是“%PATH%”,则为(
定义了rem变量
调用回显未中断输出:%%PATH%%
)
暂停>nul
@echo关闭
设置“路径=%ProgramFiles(x86)%”
回声完美输出:%PATH%
如果不是“%PATH%”,则为(
定义了rem变量
回显未中断的输出:%PATH:)=^)%
)
暂停>nul
对
NOT
用于确保变量在输出所述值之前有一个值(在本例中,它有)。NOT
是不相关的,它发生在任何使用括号的代码块中。你误解了这个问题。你会这么想的,不是吗?我才意识到它可能会被误解,所以我把它改回原来的样子。@BenHooper:仔细阅读。问题来自已解决的变量cmd
将其转换为C:\P