在我的一个脚本中,我需要在IF
语句中使用包含括号的变量,但是字符串缺少右括号或脚本过早地以* was unexpected at this time
退出(实际上不是星号) ),取决于场景。
示例
@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:\Program Files (x86)
中的右括号是IF
语句的结尾,它会在echo
完成之前退出。
有没有简单的方法来解决这个问题?最好不要求助于
IF
语句,因为我需要在其中运行多行代码,GOTO
s,因为它不实用,SETLOCAL EnableDelayedExpansion
并使用!path!
代替%path%
,因为我记得曾在某处读过该方法在操作系统中无法一致地工作。如果没有,我很乐意接受所提供的最可靠的解决方案,无论它是什么。
(这个场景不值得讨论。这只是问题的一个精炼,集中的例子。结构需要像这样,因为它在我的实际脚本中,原因我不会进入。除了这一点之外,它只会混淆事物并分散实际问题。)
答案 0 :(得分:7)
首先 - 你永远不应该使用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
编辑 - 何时使用延迟展开:对评论的回复
我通常只在需要时使用延迟扩展(或者更确切地说,当它有利时)。话虽这么说,我通常发现它在我的批处理代码的某些部分是有利的。
主要优势
echo !%1!
echo !var:%search%=%replace%!
,echo !var:%start%,%len%!
。set "var=A&B" & echo !var!
还有其他方法可以执行上述操作(除了最后一个),但延迟扩展是最简单,最有效(最快的执行)和最可靠的选项。
主要缺点
!
的任何FOR变量都将被破坏。我经常在FOR循环中打开和关闭延迟扩展以解决问题。答案 1 :(得分:1)
)
语句中已解析变量的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"
答案 2 :(得分:1)
我的建议是:
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
答案 3 :(得分:0)
原谅我,如果我读错了,但是不是“NOT”导致控制进入括号中并输出破损的输出?
怎么样:
@echo off
echo Perfect output: %programFiles(x86)%
IF NOT "%programFiles(x86^)%" == "" (
REM Variable is defined
echo Broken output: %programFiles(x86)%
)
pause >nul
答案 4 :(得分:0)
正如其他人已经指出的那样,未转义且未加引号的右括号)
会无意地结束带括号的if
块。
除了转义,引号,delayed expansion和“消失的引号”外,还有以下其他选择:
对引号使用for
元变量,并用~
-modifier删除引号:
@echo off
set "PATH=%ProgramFiles(x86)%"
echo Perfect output: %PATH%
if not "%PATH%" == "" (
rem Variable is defined
for %%P in ("%PATH%") do echo Unbroken output: %%~P
)
pause > nul
使用call
command来启动另一个变量扩展阶段,并将%
符号加倍(转义):
@echo off
set "PATH=%ProgramFiles(x86)%"
echo Perfect output: %PATH%
if not "%PATH%" == "" (
rem Variable is defined
call echo Unbroken output: %%PATH%%
)
pause > nul
通过sub-string substitution进行转义,这是在检测到^
-escaping之前发生的:
@echo off
set "PATH=%ProgramFiles(x86)%"
echo Perfect output: %PATH%
if not "%PATH%" == "" (
rem Variable is defined
echo Unbroken output: %PATH:)=^)%
)
pause > nul