【问题标题】:windows cmd: problems with for /f with a quoted command with quoted parameterswindows cmd:for /f 带有带引号参数的带引号命令的问题
【发布时间】:2017-03-02 04:28:07
【问题描述】:
for /f "delims=" %%a in ('"%systemRoot%\system32\find.exe" /?') do @echo %%a

是的,上一行有效。没有多大用处,但有效。但是尝试编写一个批处理文件来回答另一个问题,我遇到了类似

 for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v "" ^< "c:\something.txt"') do @echo %%a
 for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v ""    "c:\something.txt"') do @echo %%a

前面两行都返回The filename, directory name, or volume label syntax is incorrect

 for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v "" ^< c:\something.txt'  ) do @echo %%a
 for /f %%a in ('"%systemRoot%\system32\find.exe" /c /v ""    c:\something.txt'  ) do @echo %%a

前面两行都返回The system cannot find the file specified

我一直无法使它工作,既没有转义引号,也没有加倍引号,前面加反斜杠,将单引号改为反引号并在for 命令中设置相应的选项,我尝试的所有组合都失败了。

如果要运行的命令被引用并且它需要引用的参数,它会失败。

是的,我知道 find 周围的引号是不需要的,如果删除,前四行中的任何一行都可以工作(忽略输出、分隔符、标记)

但是在真正需要命令周围的引号的情况下(并且我知道8dot3name 行为被禁用的系统),有没有办法让它工作?我在这里错过了什么?

【问题讨论】:

    标签: windows batch-file cmd


    【解决方案1】:

    这里有两个解决方案。

    1) 包含双引号并删除了 ^ 转义字符。
    2) 在路径上使用 find。

    for /f %%a in ('""%systemRoot%\system32\find.exe" /c /v "" < "c:\something.txt""') do @echo %%a
    
    for /f %%a in (' find.exe /c /v "" ^< "c:\something.txt"') do @echo %%a
    

    这与启动一个额外的 cmd 进程来运行 for 命令中的命令行有关。

    奇怪的是,这三个命令在更简单的上下文中失败的方式不同。

    for /f %%a in (' "c:\windows\system32\find.exe" /c /v ""  something.txt ') do @echo %%a
    

    系统找不到指定的路径。

    for /f %%a in (' "c:\windows\system32\findstr.exe" /n "."  something.txt ') do @echo %%a
    

    目录名无效。

    for /f %%a in (' "c:\windows\notepad" "something.txt" ') do @echo %%a
    

    'c:\windows\notepad" "something.txt' 不是内部或外部命令、可运行程序或批处理文件。

    最后一个提供了外部引号被剥离的线索。

    Windows 8.1 32 位

    我认为在调用子进程时,cmd /? 中描述了引用问题:

    If /C or /K is specified, then the remainder of the command line after
    the switch is processed as a command line, where the following logic is
    used to process quote (") characters:
    
        1.  If all of the following conditions are met, then quote characters
            on the command line are preserved:
    
            - no /S switch
            - exactly two quote characters
            - no special characters between the two quote characters,
              where special is one of: &<>()@^|
            - there are one or more whitespace characters between the
              two quote characters
            - the string between the two quote characters is the name
              of an executable file.
    
        2.  Otherwise, old behavior is to see if the first character is
            a quote character and if so, strip the leading character and
            remove the last quote character on the command line, preserving
            any text after the last quote character.
    

    【讨论】:

    • +1 当然!!我忘了!该命令在一个新的 cmd 实例中运行。谢谢你。我无法看到这一点。在这种情况下,第二个选项(路径)被丢弃,因为原始问题似乎与干扰执行的非本机 find 命令有关。
    • 转义额外的封闭引号可能是个好主意,以免破坏命令中的引号行为:in ('^""some cmd.exe" "some|arg"^"')。另外,我不记得任何细节,但我相信 MS 文档中存在一个小缺陷 - 我认为它不能完全准确地描述引用行为。
    【解决方案2】:

    将 for 循环指令中的第一个标记放入不带引号的标记中会更容易一些。

    for /f "delims=" %%a in (
    ' if defined OS "C:\my folder with spaces\consoleapp.exe" /param1:"value" '
    )do @echo %%a
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      • 2013-12-05
      相关资源
      最近更新 更多