如何在Windows批处理文件中正确转义括号?

时间:2018-04-21 17:55:08

标签: windows batch-file

我试图在Windows批处理文件中使用这些命令行:

SET mypath="%programfiles(x86)%\Directory\SubDirectory"
SET app2="com.estrongs.android.pop_4.1.6.8.9.3-604_minAPI14(armeabi^,armeabi-v7a^,x86)(nodpi)_apkmirror.com.apk"

If Not Exist "%mypath%\includes\apk\%app2%" (
  Rem DO SOMETHING
) ELSE (
  Rem DO SOMETHING ELSE
)

但是我收到了这个错误:

(nodpi)_apkmirror.com.apk was unexpected at this time.

执行批处理文件时出现此错误消息的原因是什么?

1 个答案:

答案 0 :(得分:5)

请在Why is no string output with 'echo %var%' after using 'set var = text' on command line?上阅读我的答案,你应该明白为什么会有效:

SET "app2=com.estrongs.android.pop_4.1.6.8.9.3-604_minAPI14(armeabi,armeabi-v7a,x86)(nodpi)_apkmirror.com.apk"

注意:第一个双引号留给变量名。

命令为 SET ,参数为:

app2=com.estrongs.android.pop_4.1.6.8.9.3-604_minAPI14(armeabi,armeabi-v7a,x86)(nodpi)_apkmirror.com.apk

需要用双引号括起来以获取空格,并将这些字符&()[]{}^=;!'+,`~<|>解释为文字字符。

请勿忘记使用app2引用用双引号括起来的环境变量%app2%,或使用app2启用delayed expansion和引用变量!app2! }。

如果与其他字符串连接,则包含对环境变量app2的引用的整个参数字符串通常必须用双引号括起来。另请参阅How to set environment variables with spaces?某些应用程序(如Windows资源管理器)需要在参数字符串中引用文件/文件夹名称,而不是整个参数字符串。命令 ECHO 也是从标准:

解析的参数字符串的例外
Command "argument 1" argument2 "argument 3 with ( and ) in string"
"Path to executable\program.exe" "argument 1" argument2 "argument 3 with ( and ) in string"

示例:

@echo off
set "mypath=%TEMP%"
set "app2=com.estrongs.android.pop_4.1.6.8.9.3-604_minAPI14(armeabi,armeabi-v7a,x86)(nodpi)_apkmirror.com.apk"
if not exist "%mypath%\includes\apk\%app2%" echo File %mypath%\includes\apk\%app2% does not exist!
pause

IF 命令有4个参数字符串。

  1. 参数0是 IF 命令本身。
  2. 参数1为not
  3. 参数2为exist
  4. 参数3是文件名,其完整路径为%mypath%\includes\apk\%app2%,由于包含空格和其中一个字符&()[]{}^=;!'+,`~,因此必须用双引号括起来。
  5. 好吧,字符串%mypath%\includes\apk\%app2%不包含空格或括号。但是在debugging the batch file上可以看到Windows命令解释器在执行命令 IF <之前整个 IF 命令行的预处理期间扩展环境变量 / strong>即可。因此, IF 命令处理完整路径的文件名包含括号。

    请注意,在文本编辑器中打开的批处理文件包含的内容无关紧要。在执行命令行之前,通过Windows命令解释程序进行预处理后,命令行或以(开头并以匹配)结尾的整个命令块的外观总是很重要。

    Windows命令解释程序的帮助是cmd.exe在运行cmd /?时解释批处理文件输出,在最后一个输出帮助页面的最后一段中解释了当文件或文件夹名称必须用双引号括起来时。包含应该被解释为文字字符的重定向运算符<|>的参数字符串也必须用双引号括起来。文件/文件夹名称不能包含<|>

    批处理文件中的命令行已经过问题正确编码:

    @echo off
    set "mypath=%ProgramFiles(x86)%\MEKNYC\FireMax_Wizard"
    set "app2=com.estrongs.android.pop_4.1.6.8.9.3-604_minAPI14(armeabi,armeabi-v7a,x86)(nodpi)_apkmirror.com.apk"
    
    if not exist "%mypath%\includes\apk\%app2%" (
      echo File "%mypath%\includes\apk\%app2%" does not exist.
      rem Other commands on missing file.
    ) else (
      echo File "%mypath%\includes\apk\%app2%" exists.
      rem Other commands on existing file.
    )
    

    ECHO 命令行中,带有完整路径的文件名用双引号括起来,这在前面的示例中没有完成。原因是在预处理从{{1}开始的整个命令块期间,这两个环境变量的字符串值在{strong> ECHO 命令行中替换了%mypath%%app2% IF 命令行上,在命令 IF 执行之前,在最后一个命令行的(结束。因此,文件名中第一次出现)未用双引号括起来将被Windows命令解释器解释为真实条件的命令块结束,并且结果是错误消息。上一个示例包含一个 IF 条件,只有命令 ECHO 可以在没有以)开头的命令块的情况下执行,因此输出整个文件名是安全的用双引号括起来。但是,我强烈建议输出文件/文件夹名称,不带/带路径 ECHO 到控制台窗口(未重定向到文件中)始终用双引号括起,因为文件/文件夹字符串也可能包含&符号(会在双引号参数字符串之外的命令行上再次出现问题。