Windows cmd: 使用带引号的命令和带引号参数的for /f命令存在问题

6
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的行为),是否有任何方法使其工作?我在这里错过了什么?

2个回答

9
这里有两种解决方法: 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.

2
当然!我忘了!该命令在新的cmd实例中运行。谢谢。我之前没有注意到这一点。在这种情况下,第二个选项(路径)被舍弃,因为原始问题似乎与非本地“find”命令干扰执行有关。 - MC ND
3
为避免影响命令中的引号行为,最好去掉多余的引号,例如:in ('^""some cmd.exe" "some|arg"^"')。此外,我记不清具体细节了,但我认为微软文档存在一些小缺陷——我认为它没有完全准确地描述引号的行为。 - dbenham

0

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接