Мы провели эксперименты по изучению грамматики пакетных сценариев. Мы также исследовали различия между пакетным режимом и режимом командной строки.
Анализатор линии партии:
Вот краткий обзор этапов обработки строки кода в командном файле:
Фаза 0) Строка считывания:
Фаза 1) Процентное расширение:
Этап 1.5) Удалить <CR>
: Удалить все символы возврата каретки (0x0D)
Этап 2) Обработка специальных символов, токенизация и создание кэшированного блока команд: Это сложный процесс, на который влияют такие вещи, как кавычки, специальные символы, разделители токенов и экранирование кареток.
Фаза 3) Эхо проанализированные команды Только если командный блок не начинался с @
, и ECHO был включен в начале предыдущего шага.
Фаза 4) FOR %X
расширение переменной: Только если команда FOR активна и команды после DO обрабатываются.
Фаза 5) Отсроченное расширение: Только если включено отложенное расширение
Фаза 5.3) Обработка трубы: Только если команды находятся на любой стороне трубы
Фаза 5.5) Выполнить перенаправление:
Фаза 6) Обработка ВЫЗОВА / Удвоение каретки: Только если токен команды - ВЫЗОВ
Этап 7) Выполнить: Команда выполнена
Вот подробности для каждой фазы:
Обратите внимание, что описанные ниже этапы являются лишь моделью того, как работает пакетный анализатор. Фактические внутренние компоненты cmd.exe могут не отражать эти фазы. Но эта модель эффективна для прогнозирования поведения пакетных сценариев.
Фаза 0) Считать строку: Считать строку ввода через первый <LF>
.
- При чтении строки, которая будет проанализирована как команда,
<Ctrl-Z>
(0x1A) читается как <LF>
(LineFeed 0x0A)
- Когда GOTO или CALL читают строки во время сканирования на: метку,
<Ctrl-Z>
, обрабатывается как само по себе - не преобразуется в <LF>
Фаза 1) Процентное расширение:
- Двойной
%%
заменяется одним %
- Расширение аргументов (
%*
, %1
, %2
и т. Д.)
- Расширение
%var%
, если var не существует, заменить его ничем
- Строка сначала усекается
<LF>
не в пределах %var%
расширение
- Для полного объяснения прочитайте первую половину этого из dbenham Та же тема: Percent Phase
Этап 1.5) Удалить <CR>
: Удалить все возвраты каретки (0x0D) из строки
Этап 2) Обработка специальных символов, токенизация и создание кэшированного блока команд: Это сложный процесс, на который влияют такие вещи, как кавычки, специальные символы, разделители токенов и экранирование каретки. Далее следует приближение этого процесса.
Есть концепции, которые важны на этом этапе.
- Токен - это просто строка символов, которая рассматривается как единое целое.
- Токены разделены разделителями токенов. Стандартные разделители токенов:
<space>
<tab>
;
,
=
<0x0B>
<0x0C>
и <0xFF>
Последовательные разделители токенов рассматриваются как единое целое - между разделителями токенов нет пустых токенов
- В строке в кавычках нет разделителей токенов. Вся строка в кавычках всегда обрабатывается как часть одного токена. Один токен может состоять из комбинации строк в кавычках и символов без кавычек.
Следующие символы могут иметь особое значение на этом этапе в зависимости от контекста: ^
(
@
&
|
<
>
<LF>
<space>
<tab>
;
,
=
<0x0B>
<0x0C>
<0xFF>
Посмотрите на каждый символ слева направо:
- Если это каретка (
^
), следующий символ экранируется, и экранирующая каретка удаляется.Экранированные символы теряют все специальные значения (кроме <LF>
). - Если это кавычка (
"
), переключите флаг кавычки.Если флаг цитаты активен, то только "
и <LF>
являются специальными.Все остальные символы теряют свое особое значение, пока следующая цитата не отключит флаг кавычки.Невозможно избежать закрывающей цитаты.Все символы в кавычках всегда находятся внутри одного токена. <LF>
всегда отключает флаг кавычки.Другие поведения варьируются в зависимости от контекста, но кавычки никогда не изменяют поведение <LF>
. - Экранированный
<LF>
<LF>
убран - Следующий символ экранирован.Если в конце буфера строки, следующая строка считывается и обрабатывается фазами 1 и 1.5 и добавляется к текущей перед экранированием следующего символа.Если следующий символ -
<LF>
, то он обрабатывается как литерал, что означает, что этот процесс не является рекурсивным.
- Без экранирования
<LF>
не в скобках <LF>
удаляется и анализ текущей строки прекращается. - Все оставшиеся символы в буфере строки просто игнорируются.
- Unescaped
<LF>
в FOR INзаключенный в скобки блок <LF>
преобразуется в <space>
- Если в конце буфера строки, следующая строка считывается и добавляется к текущей.
- Unescaped
<LF>
в заключенном в скобки командном блоке <LF>
преобразуется в <LF><space>
, а <space>
обрабатывается как часть следующей строки командного блока. - Если в конце буфера строки, следующая строка читается и добавляется к пробелу.
- Если это одна изспециальные символы
&
|
<
или >
, разделите линию в этой точке, чтобыобрабатывать каналы, объединение команд и перенаправление. - В случае канала (
|
) каждая сторона представляет собой отдельную команду (или блок команд), которая получает специальную обработку в фазе 5.3 - В случае
&
,&&
или ||
объединение команд, каждая сторона объединения обрабатывается как отдельная команда. - В случае перенаправления
<
, <<
, >
или >>
предложение перенаправления анализируется, временно удаляется, а затем добавляется в конец текущей команды.Предложение перенаправления состоит из необязательной цифры дескриптора файла, оператора перенаправления и маркера назначения перенаправления. - Если токен, который предшествует оператору перенаправления, представляет собой одну цифру, то эта цифра указывает дескриптор файла для перенаправления.Если маркер маркера не найден, то по умолчанию перенаправление вывода равно 1 (стандартный вывод), а перенаправление ввода по умолчанию равно 0 (стандартный ввод).
- Если самый первыйтокен для этой команды (до перемещения перенаправления в конец) начинается с
@
, затем @
имеет особое значение.(@
не является специальным в любом другом контексте) - Специальное
@
удалено. - Если ECHO включен, то эта команда вместе со всеми последующими объединенными командами в этой строке, исключены из фазы 3 эха.Если
@
перед открытием (
, то весь блок, заключенный в скобки, исключается из эха фазы 3.
- Круглая скобка процесса (обеспечивает составные операторы в нескольких строках):
- Если анализатор не ищет токен команды, то
(
не является особенным. - Если анализатор ищет токен команды и находит
(
, тогда запустите новыйсоставной оператор и увеличение счетчика скобок - Если счетчик скобок> 0, то
)
завершает составной оператор и уменьшает счетчик скобок. - Если достигнут конец строки и счетчик скобокЕсли> 0, то следующая строка будет добавлена к составному оператору (начинается снова с фазы 0)
- Если счетчик скобок равен 0 и синтаксический анализатор ищет команду, тогда
)
функционирует подобно оператору REM
, если сразу после него следует разделитель токена, специальный символ, символ новой строки или конец. из-файла
- Все специальные символы теряют свое значение, кроме
^
(возможна конкатенация строк)
- Когда достигнут конец логической строки, вся «команда» отбрасывается.
- Каждая команда разбита на серию токенов. Первый токен всегда обрабатывается как командный токен (после удаления специального
@
и перемещения перенаправления в конец).
- Ведущие разделители токенов перед командным токеном удаляются
- При разборе токена команды,
(
действует как разделитель токена команды, в дополнение к стандартным разделителям токена
- Обработка последующих токенов зависит от команды.
- Большинство команд просто объединяют все аргументы после токена команды в токен с одним аргументом. Все разделители токенов аргументов сохраняются. Параметры аргумента обычно не анализируются до фазы 7.
- Три команды получают специальную обработку - IF, FOR и REM.
- ЕСЛИ делится на две или три отдельные части, которые обрабатываются независимо. Синтаксическая ошибка в конструкции IF приведет к фатальной синтаксической ошибке.
- Операция сравнения - это действительная команда, которая проходит всю фазу до фазы 7
- Все опции IF полностью проанализированы в фазе 2.
- Последовательные разделители маркеров сворачиваются в одно пространство.
- В зависимости от оператора сравнения могут быть определены один или два токена значения.
- Блок команд True - это набор команд после условия, который анализируется, как и любой другой блок команд. Если нужно использовать ELSE, тогда блок True должен быть заключен в скобки.
- Необязательный блок команд False - это набор команд после ELSE. Опять же, этот командный блок анализируется нормально.
- Командные блоки True и False не переходят автоматически в последующие фазы. Их последующая обработка контролируется фазой 7.
- FOR делится на две после DO. Синтаксическая ошибка в конструкции FOR приведет к фатальной синтаксической ошибке.
- Часть через DO является фактической итерационной командой FOR, которая проходит всю фазу 7
- Все опции FOR полностью анализируются в фазе 2.
- В скобках IN содержится
<LF>
как <space>
. После разбора предложения IN все токены объединяются в один токен.
- Последовательные разделители токенов без кавычек / без кавычек сворачиваются в единое пространство в команде FOR через DO.
- Часть после DO является командным блоком, который анализируется нормально. Последующая обработка командного блока DO контролируется итерацией на этапе 7.
- REM, обнаруженный в фазе 2, обрабатывается значительно иначе, чем все другие команды.
- Анализируется только один токен аргумента - анализатор игнорирует символы после первого токена аргумента.
- Если существует только один токен аргумента, который заканчивается неэкранированным
^
, заканчивающим строку, то токен аргумента отбрасывается, а последующая строка анализируется и добавляется в REM. Это повторяется до тех пор, пока не будет больше одного токена, или последний символ не будет ^
.
- Команда REM может появиться в выходных данных фазы 3, но команда никогда не выполняется, и исходный текст аргумента отображается - экранирующие символы не удаляются.
- Если жетон команды начинается с
:
, и это первый раунд фазы 2 (не перезапуск из-за ВЫЗОВА в фазе 6), тогда
- Маркер обычно обрабатывается как Неисполненная метка .
- Остальная часть строки анализируется, однако
)
, <
, >
, &
и |
больше не имеют специального значения.Весь остаток строки считается частью метки «команда». ^
продолжает быть особенным, то есть продолжение строки может использоваться для добавления следующей строки к метке. - Неисполненная метка в заключенном в скобки блоке приведет к фатальной синтаксической ошибке, если сразу за ней не последует команда или Executed Label в следующей строке.
- Обратите внимание, что
(
больше не имеет особого значения для первой команды, следующей за неисполненной меткой в этом контексте.
- Командапрервано после завершения анализа метки.Последующие этапы не выполняются для метки
- . Существуют три исключения, которые могут привести к тому, что метка, обнаруженная на этапе 2, будет рассматриваться как Executed Label , которая продолжает анализдо фазы 7.
- Существует перенаправление, которое предшествует токену метки, и существует
|
труба или &
, &&
или ||
конкатенация команд на линии. - Существует перенаправление, которое предшествует токену метки, и команда находится в блоке в скобках.
- Маркер метки является самой первой командой в строке в блоке в скобках, и строка выше заканчивалась Неисполненная метка .
- Следующее происходит, когда Исполняемая метка обнаруживается на этапе 2
- Метка, ее аргументы,и его перенаправление все исключены из любого эхо-выхода в фазе 3
- Все последующие составные команды в строке полностью анализируются и выполняются.
- Для получения дополнительной информацииинформация о Выполненные метки против Неисполненные метки , см. https://www.dostips.com/forum/viewtopic.php?f=3&t=3803&p=55405#p55405
Этап 3) Отобразите проанализированную команду(s) Только если командный блок не начинался с @
, и ECHO был включен в начале предыдущего шага.
Фаза 4) FOR %X
расширение переменной: Только если команда FOR активна и команды после DO обрабатываются.
- На этом этапе фаза 1 пакетной обработки уже преобразует переменную FOR, такую как
%%X
, в %X
.Командная строка имеет различные правила процентного расширения для фазы 1. Это причина того, что командные строки используют %X
, но командные файлы используют %%X
для переменных FOR. - Имена переменных FOR чувствительны к регистру, но
~modifiers
не чувствительны к регистру. ~modifiers
имеют приоритет над именами переменных.Если символ, следующий за ~
, является одновременно модификатором и допустимым именем переменной FOR, и существует последующий символ, который является активным именем переменной FOR, тогда этот символ интерпретируется как модификатор. - FOR имена переменныхявляются глобальными, но только в контексте предложения DO.Если подпрограмма вызывается из предложения FOR DO, то переменные FOR не раскрываются в подпрограмме CALLed.Но если у подпрограммы есть своя собственная команда FOR, то все переменные, определенные в настоящий момент, переменные FOR доступны для внутренних команд DO.
- Имена переменных FOR могут быть повторно использованы во вложенныхФорс.Внутреннее значение FOR имеет приоритет, но как только INNER FOR закрывается, восстанавливается внешнее значение FOR.
- Если ECHO был включен в начале этой фазы, то фаза 3) повторяется, чтобы показать проанализированный DOкоманды после расширения переменных FOR.
---- С этого момента каждая команда, определенная на этапе 2, обрабатывается отдельно.
----Фазы с 5 по 7 завершены для одной команды перед переходом к следующей.
Этап 5) Отложенное расширение: Только если включено отложенное расширение, команда не находится в блоке с круглыми скобками по обе стороны канала , и команда не является «голый» пакетный сценарий (имя сценария без скобок, CALL, конкатенация команд или канал).
- Каждый токен для команды анализируется для отложенного расширения независимо.
- Большинство команд анализируют два или более токенов - токен команды, токен аргументов и каждый токен назначения перенаправления.
- Команда FOR анализирует только токен предложения IN.
- Команда IF анализирует только значения сравнения - одно или два, в зависимости от оператора сравнения.
- Для каждого проанализированного токена сначала проверьте, содержит ли он
!
.Если нет, то токен не анализируется - важно для ^
символов.Если токен содержит !
, то сканируйте каждый символ слева направо: - Если это каретка (
^
), то следующий символ не имеет специального значения, сама каретка удаляется - Если это восклицательный знак, ищите следующий восклицательный знак (каретки больше не наблюдаются), развернитесь до значения переменной.
- Последовательное открытие
!
свернуто в один !
- Все оставшиеся
!
, которые не могут быть спарены, удаляются
- Расширяющиеся переменныена данном этапе это «безопасно», потому что специальные символы больше не обнаруживаются (даже
<CR>
или <LF>
) - Для более полного объяснения прочитайте вторую половину этого из dbenham та же резьба - Фаза восклицательного знака
Фаза 5.3) Обработка трубы: Только если команды находятся на любой стороне трубы
Каждая сторона канала обрабатывается независимо.
- При работе с блоком команд, заключенным в скобки, все
<LF>
с командой до и после преобразуются в <space>&
.Другие <LF>
удаляются. - Команда (или блок команд) выполняется асинхронно в новом потоке cmd.exe через
%comspec% /S /D /c" commandBlock"
.Это означает, что командный блок получает фазовый перезапуск, но на этот раз в режиме командной строки. - Это конец обработки команд канала.
- Для получения дополнительной информации о том, как анализируются каналы, иобработано, посмотрите на этот вопрос и ответы: Почему отложенное расширение завершается неудачно, когда внутри конвейерного блока кода?
Phase 5.5) Выполнить перенаправление: ЛюбойПеренаправление, обнаруженное на этапе 2, теперь выполняется.
Этап 6) Обработка ВЫЗОВА / Удвоение каретки: Только еслитокен команды - CALL, или если текст перед первым встречающимся стандартным разделителем токена - CALL.Если CALL анализируется из большого токена команды, то перед продолжением перед неиспользуемой частью добавляется токен аргументов.
- Сканирование токена аргументов для поиска без кавычек
/?
.Если найдено где-либо в пределах токенов, прервите фазу 6 и перейдите к фазе 7, где будет напечатана ПОМОЩЬ для ВЫЗОВА. - Удалите первый
CALL
, чтобы можно было сложить несколько ВЫЗОВОВ - Удвоить все каретки
- Перезапустить фазы 1, 1.5 и 2, но не переходить к фазе 3
- Любые дублированные каретки сокращаются до одной каретки, если они не указаны.Но, к сожалению, цитируемые каретки остаются удвоенными.
- Фаза 1 изменяется немного
- Ошибки расширения на шаге 1.2 или 1.3 отменяют CALL, но ошибка не является фатальной - пакетная обработка продолжается.
- Задачи Фазы 2 немного изменены
- Обнаруживается любое вновь появляющееся перенаправленное без кавычек, неэкранированное, которое не было обнаружено в первом раунде фазы 2, но оно удаляется (включая имя файла) без фактического выполнения перенаправления
- Любое вновь появляющееся без кавычек,неэкранированная каретка в конце строки удаляется без выполнения продолжения строки
- CALL прерывается без ошибок, если обнаруживается любое из следующего
- Вновь появившиеся без кавычек, неэкранированные
&
или |
- Полученный токен команды начинается с кавычек, без экранирования
(
- Самый первый токен после того, как удаленный CALL начинался с
@
- Если результирующая команда является, по-видимому, допустимой IF или FOR, то впоследствии выполнение завершится неудачно с ошибкой, сообщающей, что
IF
или FOR
не распознан как внутренняя или внешняя команда. - Конечно, CALLне прерывается во втором раунде этапа 2, если результирующий токен команды является меткой, начинающейся с
:
.
- Если результирующим токеном команды является CALL, перезапустите фазу 6 (повторяется до тех пор, пока CALL больше не будет)
- Если результирующий токен команды является пакетнымсценария или метки:, то выполнение CALL полностью обрабатывается оставшейся частью фазы 6.
- Вставьте текущую позицию файла пакетного сценария в стек вызовов, чтобы выполнение могло возобновиться с правильной позиции, когда CALLзавершено.
- Настройте токены аргументов% 0,% 1,% 2, ...% N и% * для CALL, используя все полученные токены
- Если токен команды являетсяметка, которая начинается с
:
, затем - Перезапустите этап 5. Это может повлиять на что: метка CALLed.Но поскольку токены% 0 и т. Д. Уже настроены, они не изменят аргументы, передаваемые в процедуру CALLed.
- Выполнение метки GOTO для позиционирования указателя файла в начале подпрограммы (игнорируйте любыедругие токены, которые могут следовать за: label) См. на этапе 7 правила о том, как работает GOTO.
- Иначепередать управление указанному пакетному сценарию.
- Выполнение метки или сценария CALLed: продолжается до тех пор, пока не будет достигнут EXIT / B или конец файла, после чего стек CALL выталкивается и выполнение возобновляется изпозиция сохраненного файла.
Этап 7 не выполняется для сценариев CALLed или: меток.
- В противном случае результат этапа 6 попадает в фазу 7 для выполнения.
Этап 7) Выполнить: Команда выполнена
- 7.1 - Выполнить внутреннюю команду - Если токен команды указан в кавычках, пропустить этошаг.В противном случае попытайтесь разобрать внутреннюю команду и выполнить.
- Следующие тесты выполняются, чтобы определить, представляет ли токен команды без кавычек внутреннюю команду:
- Если токен команды точно соответствует внутренней команде, то выполнить ее.
- Иначеразбить маркер команды до первого появления
+
/
[
]
<space>
<tab>
,
;
или =
Если предыдущий текст является внутренней командой, топомните, что команда - Если она находится в режиме командной строки, или если команда из блока, заключенного в скобки, командного блока ЕСЛИ истина или ложь, командного блока FOR DO или связана с объединением команд, то выполните внутреннюю команду
- В противном случае (должна быть автономной командой в пакетном режиме) сканировать текущую папку и путь к файлу .COM, .EXE, .BAT или .CMD, базовое имя которого соответствует исходному токену команды
- Если первый соответствующий файл - .BAT или .CMD, перейдите к 7.3.exec и выполните этот сценарий
- В противном случае (совпадение не найдено или первое совпадение - .EXE или .COM) выполните запомненную внутреннюю команду.
- Иначе сломайте токен команды до первого появления
.
\
или :
Если предыдущий текст не является внутренней командой, затем перейдите к 7.2
В противном случае предыдущий текст может быть внутренней командой.Запомните эту команду. - Прервите токен команды до первого появления
+
/
[
]
<space>
<tab>
,
;
или =
Если предыдущий текст представляет собой путь к существующему файлу, перейдите к 7.2
Иначе выполните запомненную внутреннюю команду.
- Если внутренняя команда анализируется из большого токена команды, тонеиспользованная часть токена команды включена в список аргументов
- То, что токен команды проанализирован как внутренняя команда, не означает, что он будет успешно выполнен.Каждая внутренняя команда имеет свои собственные правила в отношении того, как анализируются аргументы и параметры, и какой синтаксис разрешен.
- Все внутренние команды выводят справку вместо выполнения своей функции, если обнаружено
/?
.Большинство распознает /?
, если оно появляется в аргументах.Но некоторые команды, такие как ECHO и SET, выводят справку только в том случае, если маркер первого аргумента начинается с /?
. - SET имеет несколько интересных семантик:
- Если команда SET имеет кавычку перед переменнойимя и расширения разрешены
set "name=content" ignored
-> value = content
, затем текст между первым знаком равенства и последней цитатой используется в качестве содержимого (первое равно и последнеецитата исключена).Текст после последней цитаты игнорируется.Если после знака равенства нет кавычек, то остальная часть строки используется в качестве содержимого. - Если команда SET не имеет кавычек перед именем
set name="content" not ignored
-> value = "content" not ignored
тогда весь остаток строки после равенства используется в качестве содержимого, включая любые и все кавычки, которые могут присутствовать.
- AnЕсли выполняется сравнение IF, и в зависимости от того, является ли условие истинным или ложным, обрабатывается соответствующий уже проанализированный зависимый блок команд, начиная с фазы 5.
- Предложение IN команды FOR повторяется соответствующим образом.
- Если это FOR / F, который повторяет вывод командного блока, тогда:
- Предложение IN выполняется в новом процессе cmd.exe через CMD /C.
- Командный блок должен пройти весь процесс синтаксического анализа во второй раз, но на этот раз в контексте командной строки
- ECHO запустится ON, а отложенное расширение, как правило, будет отключено (зависит от реестра
- Все изменения среды, сделанные с помощью командного блока предложения IN, будут потеряны после завершения дочернего процесса cmd.exe
- Для каждой итерации:
- Определены значения переменных FOR
- Затем обрабатывается уже проанализированный командный блок DO, начиная с фазы 4.
- GOTO использует следующееЛогика для поиска: label
- Метка анализируется по первому аргументу token
- Сценарий сканируется на предмет следующего появления метки
- Сканирование начинается с текущегофайл рosition
- Если достигнут конец файла, то сканирование возвращается к началу файла и продолжается до исходной начальной точки.
- Сканирование останавливается при первом появлении найденной метки, а указатель файла устанавливается на строку, следующую непосредственно за меткой.Выполнение сценария возобновляется с этого момента.Обратите внимание, что успешное истинное GOTO немедленно прервет любой проанализированный блок кода, включая циклы FOR.
- Если метка не найдена или токен метки отсутствует, то GOTO завершается ошибкой, выводится сообщение об ошибке,и стек вызовов выталкивается.Это эффективно работает как EXIT / B, за исключением того, что все уже проанализированные команды в текущем командном блоке, которые следуют за GOTO, все еще выполняются, но в контексте CALLer (контекст, который существует после EXIT / B)
- См. https://www.dostips.com/forum/viewtopic.php?f=3&t=3803 для более точного описания правил, используемых для анализа меток.
- RENAME и COPY оба принимают подстановочные знаки для исходного и целевого путей.Но Microsoft делает ужасную работу, документируя, как работают шаблоны, особенно для целевого пути.Полезный набор правил подстановочных знаков можно найти по адресу Как команда Windows RENAME интерпретирует подстановочные знаки?
- 7.2 - Выполнить изменение тома - Другоеесли токен команды не начинается с кавычки, имеет длину ровно два символа, а 2-й символ является двоеточием, то измените громкость
- Все токены аргументов игнорируются
- Если указанный томпо первому символу не может быть найден, затем прерывается с ошибкой
- Токен команды
::
всегда будет приводить к ошибке, если SUBST не используется для определения тома для ::
Если SUBST являетсяиспользуется для определения тома для ::
, затем том будет изменен, он не будет рассматриваться как метка.
- 7.3 - Выполнить внешнюю команду -Еще попробуйте воспринимать команду как внешнюю команду.
- Если в режиме командной строки команда не указана в кавычках и не начинается со спецификации тома, то при первом появлении
<space>
,
;
или =
идобавьте остаток к токену (ам) аргумента. - Если вторым символом токена команды является двоеточие, убедитесь, что можно найти том, указанный в первом символе.
Если том не может бытьнайдено, затем прервано с ошибкой. - Если в пакетном режиме токен команды начинается с
:
, то перейдите к 7.4
Обратите внимание, что если маркер метки начинается с ::
, то это не будетбудет достигнут, потому что предыдущий шаг будет прерван с ошибкой, если SUBST не используется для определения тома для ::
. - Определите внешнюю команду для выполнения.
- Это сложный процесс, который может включать в себя текущий том, текущий каталог, переменную PATH, переменную PATHEXT и / или сопоставления файлов.
- Если допустимая внешняя команда не может быть идентифицирована, прервать ее с помощьюошибка.
- Если в режиме командной строки токен команды начинается с
:
, то переходите к 7.4
Обратите внимание, что это редко достигается, поскольку предыдущий шаг будет прерван с помощьюошибка, если токен команды не начинается с ::
, а SUBST используется для определения тома для ::
, а весь токен команды является допустимым путем к внешней команде. - 7.3.exec - выполнить внешнюю команду.
- 7.4 - игнорировать метку - игнорировать команду и все ее аргументы, если маркер команды начинается с
:
.
Правила в 7.2 и 7.3 могут препятствовать достижению меткой этой точки.
Анализатор командной строки:
Работает подобно BatchLine-Parser, за исключением:
Фаза 1) Процентное расширение:
- Нет
%*
, %1
и т. Д. Расширение аргумента - Если var не определен, то
%var%
остаетсябез изменений. - Нет специальной обработки
%%
.Если var = content, то %%var%%
расширяется до %content%
.
Этап 3) Выводит проанализированные команды (ы)
- Это не выполняется после фазы 2. Это выполняется только после фазы 4 для командного блока FOR DO.
Этап 5) Отсроченное расширение: только если DelayedExpansion имеет значениеenabled
- Если var не определено, то
!var!
остается без изменений.
Этап 7) Выполнить команду
- Попытки CALL или GOTO a: label приводят к ошибке.
- Как уже задокументировано на этапе 7, выполненная метка может привести к ошибке при различных сценариях.
- Метки, выполненные в пакетном режиме, могут вызвать ошибку, только если они начинаются с
::
- Метки, выполненные в командной строке, почти всегда вызывают ошибку
Разбор целочисленных значений
Существует множество различных контекстов, в которых cmd.exe анализирует целочисленные значения из строк, а правила противоречивы:
SET /A
IF
%var:~n,m%
(переменное расширение подстроки) FOR /F "TOKENS=n"
FOR /F "SKIP=n"
FOR /L %%A in (n1 n2 n3)
EXIT [/B] n
Подробную информацию об этих правилах можно найти в Правила того, как CMD.EXE анализирует числа
Для всех желающихДля улучшения правил разбора cmd.exe на форуме DosTips есть тема для обсуждения *1932*, где можно сообщать о проблемах и вносить предложения.
Надеюсь, что это поможет
Ян Эрик (jeb)- Оригинальный автор и первооткрыватель фаз
Дейв Бенхэм (dbenham) - Много дополнительного контента и редактирования