Istnieją metody, które pozwalają uniknąć ^
sekwencji ucieczki.
Możesz użyć zmiennych z opóźnionym rozwinięciem. Poniżej znajduje się mała demonstracja skryptu wsadowego
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
echo !line!
Lub możesz użyć pętli FOR / F. Z wiersza poleceń:
for /f "delims=" %A in ("<html>") do @echo %~A
Lub ze skryptu wsadowego:
@echo off
for /f "delims=" %%A in ("<html>") do echo %%~A
Powodem tych metod pracy jest opóźnione, ponieważ zarówno ekspansja i dla zmiennej ekspansji wystąpić po specjalnych, takich jak operatorzy <
, >
, &
, |
, &&
, ||
są analizowane. Zobacz Jak interpreter poleceń systemu Windows (CMD.EXE) analizuje skrypty? po więcej informacji.
sin3.14 wskazuje, że rury mogą wymagać wielu ucieczek . Na przykład:
echo ^^^<html^^^>|findstr .
Powodem, dla którego potoki wymagają wielu ucieczek, jest to, że każda strona potoku jest wykonywana w nowym procesie CMD, więc linia jest analizowana wiele razy. Zobacz Dlaczego opóźnione rozwijanie kończy się niepowodzeniem, gdy znajduje się wewnątrz bloku kodu potokowego? aby uzyskać wyjaśnienie wielu niewygodnych konsekwencji implementacji potoków Window.
Istnieje inna metoda uniknięcia wielokrotnych ucieczek podczas używania rur. Możesz jawnie utworzyć wystąpienie własnego procesu CMD i zabezpieczyć pojedyncze znaki ucieczki za pomocą cudzysłowów:
cmd /c "echo ^<html^>"|findstr .
Jeśli chcesz użyć techniki opóźnionego rozszerzania, aby uniknąć ucieczek, jest jeszcze więcej niespodzianek (możesz nie być zaskoczony, jeśli jesteś ekspertem w projektowaniu CMD.EXE, ale nie ma oficjalnej dokumentacji MicroSoft, która wyjaśnia te rzeczy)
Pamiętaj, że każda strona potoku jest wykonywana we własnym procesie CMD.EXE, ale proces nie dziedziczy stanu opóźnionego rozwinięcia - domyślnie jest wyłączony. Musisz więc jawnie utworzyć instancję własnego procesu CMD.EXE i użyć opcji / V: ON, aby włączyć opóźnione rozszerzanie.
@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .
Należy zauważyć, że opóźnione rozwijanie jest WYŁĄCZONE w nadrzędnym skrypcie wsadowym.
Ale piekło się rozpada, jeśli opóźniona ekspansja jest włączona w skrypcie nadrzędnym. Poniższy sposób nie działa:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .
Problem polega na tym, że !test!
jest on rozwijany w skrypcie nadrzędnym, więc nowy proces CMD próbuje przeanalizować niezabezpieczone pliki <
i >
.
Możesz uciec od !
, ale to może być trudne, ponieważ zależy to od tego, czy !
jest cytowany, czy nie.
Jeśli nie jest cytowany, wymagana jest podwójna ucieczka:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo ^^!test^^!|findstr .
Jeśli jest cytowany, to używana jest pojedyncza ucieczka:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c "echo ^!test^!"|findstr .
Ale jest zaskakująca sztuczka, która pozwala uniknąć wszystkich ucieczek - zamknięcie lewej strony potoku zapobiega !test!
przedwczesnemu rozszerzaniu się skryptu nadrzędnego :
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
(cmd /v:on /c echo !test!)|findstr .
Ale przypuszczam, że nawet to nie jest darmowy obiad, ponieważ parser wsadowy wprowadza dodatkową (być może niechcianą) przestrzeń na końcu, gdy używane są nawiasy.
To nie zabawa ze skryptami wsadowymi ;-)