如何在批处理文件中的 if 子句中使用括号转义变量?

发布于 2024-12-10 17:09:08 字数 229 浏览 0 评论 0原文

运行此批处理文件

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=%a%
)

会出现 inside was Outstanding at this time. 错误。

如何转义 a 变量以避免此错误?

Running this batch file

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=%a%
)

gives inside was unexpected at this time. error.

How to escape a variable to avoid this error?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

牵强ㄟ 2024-12-17 17:09:08

您可以使用两种不同的方式

使用带有引号的 set 扩展语法set "var=content" 将设置 var 与内容,
内容被引用,因此特殊字符不会有问题,并且它使用直到最后一个引用的内容(没有引用本身)

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set "PATH=%a%"
)

使用延迟扩展(如 shf301 的答案),但也将值传输到主范围。

@echo off
setlocal enabledelayedexpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set "localScope_PATH=!a!"
    rem now transfer it to the global scope
    FOR /F "delims=" %%A in ("!localScope_PATH!") DO (
       endlocal
       set "path=%%A"
    )
)

在这种情况下,扩展的集合语法是不必要的,我使用它只是为了避免行尾的隐藏空格。

编辑:
我可以将其与 setlocal EnableDelayedExpansion 结合起来并使用 !而不是 % 来延迟评估变量的值?当我尝试时,我得到了)!此时出乎意料。

你可以,但它具有相反的生产力,因为

@echo off
Setlocal EnableDelayedExpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=!a:^)=^^^)!
    set path
)

那么你的路径在 ) 前面包含插入符号
C:\programs (x86^)

要了解扩展的工作原理,您可以阅读 SO:Windows 命令解释器 (CMD.EXE) 如何解析脚本?

EDIT2:路径有更多问题(包含引号)
根据这个 问题,当路径包含引号。

样品
path="C:\Program Files (x86)";C:\Program Files (x86)\Skype

这是允许的,即使这里没有必要使用引号,但这会破坏扩展的 SET 语法,现在 set "newPath=%path%" 扩展为

set "newPath="C:\Program Files (x86)";C:\Program Files (x86)\Skype"

现在至少有一个括号不在引号内,并且能够中断命令块。

但是您可以简单地从路径变量中删除所有引号,如上所述,此处不需要引号。

set "newPath=%path:"=%"

You can use two different ways

Use the extended syntax of set with quotes set "var=content" will set var with content,
content is quoted so special characters aren't problematic and it uses the content till the last quote (without the quote itself)

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set "PATH=%a%"
)

Use delayed expansion (like the answer of shf301) but also transfer the value to the main scope.

@echo off
setlocal enabledelayedexpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set "localScope_PATH=!a!"
    rem now transfer it to the global scope
    FOR /F "delims=" %%A in ("!localScope_PATH!") DO (
       endlocal
       set "path=%%A"
    )
)

In this case the extended set-syntax is not necessary, I used it only to avoid hidden spaces at the line end.

EDIT:
Can I combine this with setlocal EnableDelayedExpansion and using ! instead of % to lazy evaluate variable's value? When I tried I got )! was unexpected at this time.

You can, but it's contra productive, as

@echo off
Setlocal EnableDelayedExpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=!a:^)=^^^)!
    set path
)

Then your path contains carets in front of the ) like
C:\programs (x86^)

To understand how expansion works you can read SO:How does the Windows Command Interpreter (CMD.EXE) parse scripts?

EDIT2: More problems with the path (containing quotes)
According to this question there can occour another problem with parenthesis when the path contains quotes.

Sample
path="C:\Program Files (x86)";C:\Program Files (x86)\Skype

This is allowed, even it's not necessary to use quotes here, but this destroys the extended SET syntax, as now set "newPath=%path%" expands to

set "newPath="C:\Program Files (x86)";C:\Program Files (x86)\Skype"

Now at least one parenthesis is not inside quotes and is able to break a command block.

But you can simply remove all quotes from the path variable, as said, quotes aren't necessary here.

set "newPath=%path:"=%"
苍暮颜 2024-12-17 17:09:08

%a% 中的 ) 就是这里的问题。您只需进行一些替换即可转义 )

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=%a:)=^)%
)

The ) in %a% is the problem here. You can just do some substitution to escape the ).

@echo off
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=%a:)=^)%
)
小情绪 2024-12-17 17:09:08

使用延迟扩展将解决这个问题:

@echo off
setlocal enabledelayedexpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=!a!
)

如果没有延迟扩展,if 块(从 if 到结尾 ,首先替换 %a%,然后解析并运行该块。延迟扩展!a!解析块后不会扩展。因此解析逻辑不会在 a 中看到 ) 并且不会导致问题。

Using delayed expansion will fix that:

@echo off
setlocal enabledelayedexpansion
set a=some value with (parentheses) inside
if 1 == 1 (
    set PATH=!a!
)

Without delayed expansion the if block (from the if to the ending ), %a% is replaced first and then the block is parsed and run. With delayed expansion !a! isn't expanded after the block parsed. So the parsing logic won't see the ) in a and won't cause it issues.

掩耳倾听 2024-12-17 17:09:08

括号和变量的混合总是很痛苦。请改用子例程。

@Echo Off
Set a=some value with (parentheses) inside
If 1 == 1 Call :SetPath
Echo %Path%
Exit /B

:SetPath
Set "Path=%a%"
SetX "Path" "%a%"
Exit /B

我设置该变量两次,一次使用 Set 为当前 shell 会话,一次使用 SetX 在系统范围内为将来的 shell 会话设置它。如果不需要,请将其删除。

Brackets and variables are always a pain to mix. Use a subroutine instead.

@Echo Off
Set a=some value with (parentheses) inside
If 1 == 1 Call :SetPath
Echo %Path%
Exit /B

:SetPath
Set "Path=%a%"
SetX "Path" "%a%"
Exit /B

I set the variable twice, once using Set for the current shell session, and one using SetX to set it system-wide for future shell sessions. Remove either if they're unneeded.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文