Существуют методы, которые избегают ^
escape-последовательностей.
Вы можете использовать переменные с отложенным расширением. Ниже приведен небольшой пакетный сценарий демонстрации
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
echo !line!
Или вы можете использовать цикл FOR / F. Из командной строки:
for /f "delims=" %A in ("<html>") do @echo %~A
Или из пакетного сценария:
@echo off
for /f "delims=" %%A in ("<html>") do echo %%~A
Причина, по которой эти методы работают, заключается в том, что как отложенное расширение, так и расширение переменной FOR происходят после специальных операторов, таких как <
, >
, &
, |
, &&
, ||
. См. Как интерпретирует сценарии интерпретатора команд Windows (CMD.EXE)? для получения дополнительной информации.
sin3.14 указывает, что для труб может потребоваться несколько экранирований . Например:
echo ^^^<html^^^>|findstr .
Причина, по которой каналы требуют нескольких выходов, заключается в том, что каждая сторона канала выполняется в новом процессе CMD, поэтому строка анализируется несколько раз. См. Почему отложенное расширение завершается неудачно, когда внутри конвейерного блока кода? для объяснения многих неловких последствий реализации канала Window.
Существует другой способ избежать множественных выходов при использовании каналов. Вы можете явно создать свой собственный процесс CMD и защитить одиночный escape с помощью кавычек:
cmd /c "echo ^<html^>"|findstr .
Если вы хотите использовать метод отложенного расширения, чтобы избежать побегов, то есть еще больше сюрпризов (вы можете не удивляться, если вы являетесь экспертом по разработке CMD.EXE, но нет официальной документации MicroSoft, которая объясняет этот материал)
Помните, что каждая сторона канала выполняется в своем собственном процессе CMD.EXE, но этот процесс не наследует состояние отложенного расширения - по умолчанию он выключен. Поэтому вы должны явно создать свой собственный процесс CMD.EXE и использовать параметр / V: ON, чтобы включить отложенное расширение.
@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .
Обратите внимание, что отложенное расширение отключено в родительском пакетном скрипте.
Но все чертовски разрушается, если в родительском скрипте включено отложенное расширение. Следующее не работает:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .
Проблема в том, что !test!
раскрывается в родительском скрипте, поэтому новый процесс CMD пытается проанализировать незащищенные <
и >
.
Вы можете избежать !
, но это может оказаться сложным, потому что это зависит от того, указан !
в кавычках или нет.
Если не указано, требуется двойное экранирование:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo ^^!test^^!|findstr .
Если указано, то используется один escape:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c "echo ^!test^!"|findstr .
Но есть удивительный трюк, который избегает всех побегов - закрытие левой стороны канала предотвращает преждевременное расширение родительского скрипта !test!
:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
(cmd /v:on /c echo !test!)|findstr .
Но я полагаю, что даже это не бесплатный обед, поскольку пакетный парсер вводит дополнительное (возможно, нежелательное) пространство в конце при использовании скобок.
Aint пакетного сценария весело; -)