Windows CMD - Почему обе каретки перед восклицательным знаком удаляются при отключении расширения с задержкой? - PullRequest
3 голосов
/ 09 июля 2019

Я пытаюсь понять, как работает синтаксический анализатор Windows CMD.Я читал несколько сообщений о синтаксическом анализаторе CMD, включая этот one , но я не могу понять, почему оба символа вставки (^) в следующем коде удаляются при отключении отложенного расширения:

@echo off

setlocal disabledelayedexpansion

set $test_var=This is text with escaped delayed expansion syntax - ^^!$var1^^! and ^^!$var2^^!

echo $test_var = %$test_var%

echo.
pause

Я ожидал, что в результате выполнения кода будет получен следующий вывод:

$test_var = This is text with escaped delayed expansion syntax - ^!$var1^! and ^!$var2^!

Вместо этого удаляются ВСЕ каретки:

$test_var = This is text with escaped delayed expansion syntax - !$var1! and !$var2!

При чтении post о синтаксическом анализаторе. Насколько я понимаю, на этапе 2 удаляются специальные символы, включая escape-символ (^).Из моего чтения кажется, что только один (1) символ каретки должен быть удален.Почему удаляются обе каретки?

Спасибо за помощь!

1 Ответ

3 голосов
/ 10 июля 2019

Ключом к ответу является тот факт, что нормальное (% -) расширение (фаза 1) происходит за до распознавания специальных символов (в фазе 2) - см. Принятый ответ: Как интерпретирует сценарии интерпретатора команд Windows (CMD.EXE)?


Первые символы (^) удаляются интерпретатором команд в строке

set $test_var=This is text with escaped delayed expansion syntax - ^^!$var1^^! and ^^!$var2^^!

когда завершена фаза 2, каждый экземпляр ^^ становится одним литералом ^.Вы можете доказать это, изменив @echo off на @echo on, чтобы каждая проанализированная командная строка отображалась перед выполнением или когда вы помещаете следующую команду в следующую строку (спасибо пользователю jeb за подсказка ):

rem // This displays the actual content of the variable:
set $test_var

В следующей строке

echo $test_var = %$test_var%

происходит удаление оставшихся кареток, потому что - как уже было сказано - %- сначала происходит расширение (фаза 1), в результате чего появляется командная строка типа

echo $test_var = This is text with escaped delayed expansion syntax - ^!$var1^! and ^!$var2^!

, а затем следует фаза 2, где оставшиеся каретки распознаются и удаляются, в результате чего получается окончательный текст

$test_var = This is text with escaped delayed expansion syntax - !$var1! and !$var2!

Вы можете защитить каретки (а также любые другие специальные символы) в командной строке set при использовании цитируемого синтаксиса, например:

set "$test_var=This is text with escaped delayed expansion syntax - ^!$var1^! and ^!$var2^!"

Таким образом, вы можете сохранить одинуровень , выходящий .Однако это работает только тогда, когда включены расширения команды , но это все равно значение по умолчанию для интерпретатора команд.

Для командной строки echo вы не можете использовать такойметод, потому что кавычки тоже стали возвращаться.


Я заметил, что вы использовали echo. для вывода пустой строки.Вам лучше использовать echo/ или echo( (обратитесь к внешнему ресурсу ECHO. Сбой, чтобы дать текст или пустую строку - вместо этого используйте ECHO / , чтобы выяснить, почему).


Кстати, отображаемый вами текст не соответствует реальной ситуации, потому что у вас отключено отложенное расширение .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...