Esistono metodi che evitano le ^
sequenze di escape.
È possibile utilizzare variabili con espansione ritardata. Di seguito è riportata una piccola dimostrazione di script batch
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
echo !line!
Oppure potresti usare un ciclo FOR / F. Dalla riga di comando:
for /f "delims=" %A in ("<html>") do @echo %~A
O da uno script batch:
@echo off
for /f "delims=" %%A in ("<html>") do echo %%~A
La ragione per cui questi metodi di lavoro è a causa sia l'espansione ritardata e per l'espansione variabile si verificano dopo gli operatori speciali come <
, >
, &
, |
, &&
, ||
vengono analizzati. Vedi Come vengono analizzati gli script da Command Interpreter (CMD.EXE) di Windows? per maggiori informazioni.
sin3.14 sottolinea che i tubi possono richiedere più escape . Per esempio:
echo ^^^<html^^^>|findstr .
Il motivo per cui le pipe richiedono più escape è perché ogni lato della pipe viene eseguito in un nuovo processo CMD, quindi la riga viene analizzata più volte. Vedi Perché l'espansione ritardata non riesce quando all'interno di un blocco di codice reindirizzato? per una spiegazione di molte conseguenze scomode dell'implementazione del pipe di Windows.
Esiste un altro metodo per evitare più escape quando si utilizzano pipe. Puoi creare un'istanza esplicita del tuo processo CMD e proteggere il singolo escape con virgolette:
cmd /c "echo ^<html^>"|findstr .
Se vuoi utilizzare la tecnica di espansione ritardata per evitare fughe, allora ci sono ancora più sorprese (potresti non essere sorpreso se sei un esperto del design di CMD.EXE, ma non esiste una documentazione ufficiale MicroSoft che spieghi queste cose)
Ricorda che ogni lato della pipe viene eseguito nel proprio processo CMD.EXE, ma il processo non eredita lo stato di espansione ritardata: il valore predefinito è OFF. Quindi è necessario creare un'istanza esplicita del proprio processo CMD.EXE e utilizzare l'opzione / V: ON per abilitare l'espansione ritardata.
@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .
Tieni presente che l'espansione ritardata è disattivata nello script batch principale.
Ma si scatena l'inferno se l'espansione ritardata è abilitata nello script principale. Quanto segue non funziona:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .
Il problema è che !test!
è espanso nello script principale, quindi il nuovo processo CMD sta tentando di analizzare non protetti <
e >
.
Potresti sfuggire al !
, ma questo può diventare complicato, perché dipende dal fatto che !
sia citato o meno.
Se non citato, è richiesta una doppia escape:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo ^^!test^^!|findstr .
Se citato, viene utilizzata una singola escape:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c "echo ^!test^!"|findstr .
Ma c'è un trucco sorprendente che evita tutte le fughe: racchiudere il lato sinistro del pipe impedisce allo script genitore di espandersi !test!
prematuramente:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
(cmd /v:on /c echo !test!)|findstr .
Ma suppongo che anche questo non sia un pranzo gratuito, perché il parser batch introduce uno spazio extra (forse indesiderato) alla fine quando vengono utilizzate le parentesi.
Non è divertente creare script in batch ;-)