gpt4 book ai didi

batch-file - 为什么文件的存在会影响其文件路径在批处理脚本中的解析方式?

转载 作者:行者123 更新时间:2023-12-04 00:41:20 25 4
gpt4 key购买 nike

当与 /f 和命令一起使用时,我对批处理 for 命令的工作方式有些不理解。

我试图循环执行可执行文件的输出。可执行文件结果不存在,这很好。

但是,脚本似乎自发地错误地标记了字符串,而不是得到关于错误路径的预期错误。这让我陷入了一个兔子洞,以为我格式化了 for 循环和/或错误地使用了引号或反引号。

将可执行文件放置在该位置可解决问题,使其看起来像路径字符串标记取决于该路径中实际文件的存在。

为什么会出现下面的批处理文件

@echo off
for /f "usebackq delims=" %%i in ( `"C:\Program Files\BOGUS_PATH\FAKE.exe"`) do (
rem
)

输出'C:\Program'不是内部或外部命令、可运行程序或批处理文件。而不是系统找不到指定的路径。 ?

最佳答案

首先,我的一个小毛病,usebackq 是不需要的。更简单且功能等效的命令是

@echo off
for /f "delims=" %%i in ('"C:\Program Files\BOGUS_PATH\FAKE.exe"') do (
rem
)

唯一需要 usebackq 的情况是当您尝试读取文件时,并且文件路径包含空格等标记分隔符。

for /f "usebackq" %%A in ('"some file.txt"')

所有其他情况都可以使用“正常”形式

for /f %%A in (fileName) do...
for /f %%A in ("string") do...
for /f %%A in ('someCommand') do...

现在回答你的实际问题:-)

文件的存在与否实际上并不会改变解析。

首先,您需要了解尝试从命令行执行不存在的程序时可能出现的错误消息。有三种可能:

1) 如果“命令”在第二个位置以外的任何地方都包含冒号,那么您可能会得到以下内容

c:\test\>abc:fake.exe
The filename, directory name, or volume label syntax is incorrect.

c:\test\>abc:\test\fake.exe
The filename, directory name, or volume label syntax is incorrect.

或者有时您会遇到下一个可能的错误。关于你收到哪条消息的规则对我来说并不明显,我觉得弄清楚确切的规则并不重要。

2)如果“命令”包含一个反斜杠表示路径,并且路径无效,那么你得到

c:\test\>c:bogus\fake.exe
The system cannot find the path specified.

c:\test\>\bogus\fake.exe
The system cannot find the path specified.

c:\test\>abc:bogus\fake.exe
The system cannot find the path specified.

3)如果找不到可执行文件,并且“命令”不包含路径信息或提供的路径有效,那么您会得到

C:\test\>fake.exe
'fake.exe' is not recognized as an internal or external command,
operable program or batch file.

C:\test>c:\test\fake.exe
'c:\test\fake.exe' is not recognized as an internal or external command,
operable program or batch file.

最后一个难题是为什么 "C:\Program Files\BOGUS_PATH\FAKE.exe" 给出错误 3) 而不是 2)

如果您从带有引号的命令行执行,那么您会得到预期的结果:

C:\test>"C:\Program Files\BOGUS_PATH\FAKE.exe"
The system cannot find the path specified.

如果你从不带引号的命令行执行,那么你会得到这个预期的结果:

C:\test>C:\Program Files\BOGUS_PATH\FAKE.exe
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

您的脚本包含引号,因此您会期待前者,但您会得到后者。

理解这一点有两个部分。

首先,FOR/F 通过执行来执行命令

C:\WINDOWS\system32\cmd.exe /c "C:\Program Files\BOGUS_PATH\FAKE.exe"

您可能认为您的“命令”被引用了,但 cmd.exe 玩游戏时带有引号,这是解释的第二部分。 cmd.exe的引用规则在帮助中有说明:

c:\test\>help cmd
Starts a new instance of the Windows command interpreter
...
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. 下的大多数条件都满足除了,最后一个条件 - 字符串不指向有效的可执行文件。所以使用了2.规则,于是命令就变成了

C:\Program Files\BOGUS_PATH\FAKE.exe

现在结果非常合理——“命令”在空格处中断。

'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

如果您尝试使用 FOR/F 执行命令,并且该命令必须用引号引起来,那么您必须在整个命令周围加上一组额外的引号。

for /f "delims=" %%A in ('""c:\some path\file.exe" "arg 1" arg2"') do ...

但是如果路径或引用的参数中有毒字符,上面会出现问题,因为额外的引号集会混淆引用。你可以逃避像

这样的毒字符
for /f "delims=" %%A in ('""c:\some path\file.exe" "this^&that" arg2"') do ...

但我觉得这很尴尬,因为您在命令行中使用的命令与您在 FOR/F 中使用的命令不匹配。我更喜欢转义额外的封闭引号集,以便命令行上的任何工作也适用于 FOR/F.

for /f "delims=" %%A in ('^""c:\some path\file.exe" "this&that" arg2^"') do ...

关于batch-file - 为什么文件的存在会影响其文件路径在批处理脚本中的解析方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55978586/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com