如何从 Windows forfiles 命令中 运行 一个带有完整路径的命令?
How do you run a command with a full path from the Windows forfiles command?
我正在尝试 运行 以下命令:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c ""C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe @path /classes"""
然而,它失败了:
ERROR: Invalid argument/option - 'Files'.
Type "FORFILES /?" for usage.
这些也不起作用:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c \"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe\" @path /classes"
forfiles /p ..\Schemas /m *.xsd /c "cmd /c ^"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe^" @path /classes"
肯定是失败了,因为传递给 cmd
的路径包含空格。你通常通过引用整个论点来解决这个问题。但是,似乎没有办法传递双引号。
那么,你如何运行一个带有来自 Windows forfiles 命令的完整路径的命令?
在您的第一次尝试中,您尝试在 cmd /c
之后在整个命令行周围放置(额外的)引号,而不是仅在可执行文件的路径周围放置引号,这将失败,因为 cmd
尝试查找并执行整行作为命令。因此,您需要在 xsd.exe
之后立即移动结束引号,而不是在命令行末尾。
不过,总的来说,这里的主要问题是 cmd
和 forfiles
处理引号的方式不同。 forfiles
使用 \"
转义引号,但 cmd
不关心反斜杠。此外,如果您的代码出现在带括号的代码块中,如果它们没有出现在 cmd
的引号中,则路径中的文字括号可能会造成额外的麻烦。最后,cmd
可能会尝试去掉引号(意外),这可能会导致更多问题。
为了解决这一切,使用另一种方法在/C
之后为命令行提供文字引号:forfiles
支持通过0xHH
表示法中的十六进制代码指定字符;所以声明 0x22
隐藏父 cmd
实例的引号,直到实际执行命令行:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c 0x220x22C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe0x22 @path /classes0x22"
这会导致执行以下命令行(使用 "D:\Data\Schemas\sample.xsd"
作为 @path
的示例值):
cmd /c ""C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe" "D:\Data\Schemas\sample.xsd" /classes"
最后,通过cmd
去掉最外面的引号后,执行下面的命令行:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe" "D:\Data\Schemas\sample.xsd" /classes
请注意 @path
,以及 forfiles
的所有其他与文件名和路径相关的 @
样式变量扩展为已引用的值。
最初,我完全忘记了 cmd
试图去掉引号这一事实。 Klitos Kyriacou's 让我想起了这一点;所以如果你喜欢我的回答,请不要忘记给他们点赞哦!
这不是 forfiles
的错;这是 cmd.exe 处理引号的方式。它本质上是为了自己的利益而试图变得太聪明。 CMD /C
命令可以将任意行作为命令,包括包含空格的行;但是,如果在 CMD /C
之后给出的命令行以引号开头,它会在尝试执行之前从该行中删除第一个和最后一个引号。因此,这两行完全等价:
cmd /c echo hello
cmd /c "echo hello"
现在的问题是引号在以下命令中被删除:
cmd /c "C:\Program Files\xyz\abc.exe" one two
为了让它做你想做的事,你需要用引号将整个东西括起来(内部引号不需要转义):
cmd /c ""C:\Program Files\xyz\abc.exe" one two"
现在,您可以将其放入 FORFILES
命令中。 FORFILES要求引号用\
转义,所以我们需要这样写:
forfiles /c "cmd /c \"\"C:\Program Files\xyz\abc.exe\" one two\""
或者在您的具体情况下:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c \"\"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe\" @path /classes\""
(请注意,CMD
的所有引号都已转义,但外引号用于 FORFILES
,因此未转义。)
我正在尝试 运行 以下命令:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c ""C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe @path /classes"""
然而,它失败了:
ERROR: Invalid argument/option - 'Files'.
Type "FORFILES /?" for usage.
这些也不起作用:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c \"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe\" @path /classes"
forfiles /p ..\Schemas /m *.xsd /c "cmd /c ^"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe^" @path /classes"
肯定是失败了,因为传递给 cmd
的路径包含空格。你通常通过引用整个论点来解决这个问题。但是,似乎没有办法传递双引号。
那么,你如何运行一个带有来自 Windows forfiles 命令的完整路径的命令?
在您的第一次尝试中,您尝试在 cmd /c
之后在整个命令行周围放置(额外的)引号,而不是仅在可执行文件的路径周围放置引号,这将失败,因为 cmd
尝试查找并执行整行作为命令。因此,您需要在 xsd.exe
之后立即移动结束引号,而不是在命令行末尾。
不过,总的来说,这里的主要问题是 cmd
和 forfiles
处理引号的方式不同。 forfiles
使用 \"
转义引号,但 cmd
不关心反斜杠。此外,如果您的代码出现在带括号的代码块中,如果它们没有出现在 cmd
的引号中,则路径中的文字括号可能会造成额外的麻烦。最后,cmd
可能会尝试去掉引号(意外),这可能会导致更多问题。
为了解决这一切,使用另一种方法在/C
之后为命令行提供文字引号:forfiles
支持通过0xHH
表示法中的十六进制代码指定字符;所以声明 0x22
隐藏父 cmd
实例的引号,直到实际执行命令行:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c 0x220x22C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe0x22 @path /classes0x22"
这会导致执行以下命令行(使用 "D:\Data\Schemas\sample.xsd"
作为 @path
的示例值):
cmd /c ""C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe" "D:\Data\Schemas\sample.xsd" /classes"
最后,通过cmd
去掉最外面的引号后,执行下面的命令行:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe" "D:\Data\Schemas\sample.xsd" /classes
请注意 @path
,以及 forfiles
的所有其他与文件名和路径相关的 @
样式变量扩展为已引用的值。
最初,我完全忘记了 cmd
试图去掉引号这一事实。 Klitos Kyriacou's
这不是 forfiles
的错;这是 cmd.exe 处理引号的方式。它本质上是为了自己的利益而试图变得太聪明。 CMD /C
命令可以将任意行作为命令,包括包含空格的行;但是,如果在 CMD /C
之后给出的命令行以引号开头,它会在尝试执行之前从该行中删除第一个和最后一个引号。因此,这两行完全等价:
cmd /c echo hello
cmd /c "echo hello"
现在的问题是引号在以下命令中被删除:
cmd /c "C:\Program Files\xyz\abc.exe" one two
为了让它做你想做的事,你需要用引号将整个东西括起来(内部引号不需要转义):
cmd /c ""C:\Program Files\xyz\abc.exe" one two"
现在,您可以将其放入 FORFILES
命令中。 FORFILES要求引号用\
转义,所以我们需要这样写:
forfiles /c "cmd /c \"\"C:\Program Files\xyz\abc.exe\" one two\""
或者在您的具体情况下:
forfiles /p ..\Schemas /m *.xsd /c "cmd /c \"\"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\xsd.exe\" @path /classes\""
(请注意,CMD
的所有引号都已转义,但外引号用于 FORFILES
,因此未转义。)