Во-первых, моя любимая мозоль, 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) Если «команда» включает двоеточие в любом месте, кроме 2-й позиции, то вы можете получить следующее
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 ...