98 votes

Échapper aux crochets d'angle dans une invite de commande Windows

Je dois envoyer une chaîne de caractères contenant des crochets (< et >) vers un fichier sur une machine Windows. En gros, ce que je veux faire est le suivant :
echo some string < with angle > brackets >>myfile.txt

Cela ne fonctionne pas car l'interpréteur de commandes s'embrouille avec les crochets. Je pourrais citer la chaîne entière comme ceci :
echo "some string < with angle > brackets" >>myfile.txt

Mais alors j'ai des guillemets dans mon fichier que je ne veux pas.

Echapper les parenthèses comme sous Unix ne fonctionne pas non plus :
echo some string \< with angle \> brackets >>myfile.txt

Des idées ?

6 votes

Les citations seront également répercutées.

175voto

Tim Robinson Points 28696

Le caractère d'échappement de Windows est ^, pour une raison quelconque.

echo some string ^< with angle ^> brackets >>myfile.txt

10 votes

En fait, la barre oblique inversée est utilisée pour les noms de chemin et le guillemet double est utilisé pour envelopper les noms de fichiers qui contiennent des espaces, donc il ne reste pas beaucoup de choix de caractères.

0 votes

Cela fonctionne également pour d'autres caractères comme l'esperluette (&), merci.

2 votes

Fonctionne très bien ! echo some string ^< with angle ^> brackets >>con résulte dans : une chaîne de caractères < avec des crochets >

26voto

sin3.14 Points 103

C'est vrai, le caractère d'échappement officiel est ^ mais faites attention car parfois vous avez besoin trois ^ des personnages. C'est juste parfois :

C:\WINDOWS> echo ^<html^>
<html>

C:\WINDOWS> echo ^<html^> | sort
The syntax of the command is incorrect.

C:\WINDOWS> echo ^^^<html^^^> | sort
<html>

C:\WINDOWS> echo ^^^<html^^^>
^<html^>

Une astuce pour sortir de ce non-sens est d'utiliser une commande autre que echo pour effectuer la sortie et la citer avec des guillemets doubles :

C:\WINDOWS> set/p _="<html>" <nul
<html>
C:\WINDOWS> set/p _="<html>" <nul | sort
<html>

Notez que cela ne préservera pas les espaces en tête du texte de l'invite.

2 votes

Voir la 2ème partie de ma réponse pour une explication de la raison pour laquelle les tuyaux nécessitent des échappatoires multiples.

1 votes

Les trois ^^^ sont également nécessaires pour échapper aux commandes dans la console Azure DOS/Kudu.

0 votes

J'ai constaté que cela est effectivement nécessaire lorsque vous voulez stocker une valeur contenant des brackers pointus dans le keyvault Azure via le CLI Azure.

9voto

dbenham Points 46458

Il existe des méthodes qui évitent ^ les séquences d'échappement.

Vous pourriez utiliser des variables à expansion différée. Voici une démonstration d'un petit lot de script.

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
echo !line!

Ou vous pouvez utiliser une boucle FOR /F. Depuis la ligne de commande :

for /f "delims=" %A in ("<html>") do @echo %~A

Ou à partir d'un script batch :

@echo off
for /f "delims=" %%A in ("<html>") do echo %%~A

La raison pour laquelle ces méthodes fonctionnent est que l'expansion retardée et l'expansion de la variable FOR se produisent après des opérateurs spéciaux tels que < , > , & , | , && , || sont analysés. Voir Comment l'interpréteur de commandes Windows (CMD.EXE) analyse-t-il les scripts ? pour plus d'informations.


sin3.14 signale que les tuyaux peuvent nécessiter des échappatoires multiples . Par exemple :

echo ^^^<html^^^>|findstr .

La raison pour laquelle les tuyaux nécessitent plusieurs échappatoires est que chaque côté du tuyau est exécuté dans un nouveau processus CMD, de sorte que la ligne est analysée plusieurs fois. Voir Pourquoi l'expansion retardée échoue-t-elle à l'intérieur d'un bloc de code pipé ? pour une explication des nombreuses conséquences gênantes de l'implémentation des tuyaux dans Windows.

Il existe une autre méthode pour éviter les échappatoires multiples lors de l'utilisation de tuyaux. Vous pouvez instancier explicitement votre propre processus CMD, et protéger l'échappement unique avec des guillemets :

cmd /c "echo ^<html^>"|findstr .

Si vous voulez utiliser la technique d'expansion retardée pour éviter les échappements, alors il y a encore plus de surprises (Vous ne serez peut-être pas surpris si vous êtes un expert de la conception de CMD.EXE, mais il n'y a pas de documentation officielle de MicroSoft qui explique ces choses)

Rappelez-vous que chaque côté du tuyau est exécuté dans son propre processus CMD.EXE, mais le processus ne fait pas no héritent de l'état d'expansion retardée - il est désactivé par défaut. Vous devez donc instancier explicitement votre propre processus CMD.EXE et utiliser l'option /V:ON pour activer l'expansion différée.

@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .

Notez que l'expansion retardée est désactivée dans le lot parent script.

Mais l'enfer se déchaîne si l'expansion différée est activée dans le script parent. Ce qui suit fait no travail :

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .

Le problème est que !test! est développé dans le script parent, donc le nouveau processus CMD essaye d'analyser des données non protégées. < y > .

Vous pourriez échapper à la ! mais cela peut s'avérer délicat, car cela dépend de l'existence ou non d'un lien entre l'utilisateur et l'entreprise. ! est cité ou non.

S'il n'est pas cité, un double échappement est nécessaire :

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo ^^!test^^!|findstr .

S'il est cité, un seul échappement est utilisé :

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c "echo ^!test^!"|findstr .

Mais il existe une astuce surprenante qui permet d'éviter tous les échappements - en enfermant le côté gauche du tuyau, on empêche le script parent de se développer. !test! prématurément :

@echo off
setlocal enableDelayedExpansion
set "line=<html>"
(cmd /v:on /c echo !test!)|findstr .

Mais je suppose que même cela n'est pas gratuit, car l'analyseur syntaxique par lots introduit un espace supplémentaire (peut-être indésirable) à la fin lorsque des parenthèses sont utilisées.

C'est amusant, le scripting par lot ;-)

3voto

orbitcowboy Points 797

Pour utiliser des caractères spéciaux, tels que '>' sous Windows avec echo, vous devez les faire précéder d'un caractère d'échappement spécial.

Par exemple

echo A->B

ne fonctionnera pas puisque '>' doit être échappé par '^' :

 echo A-^>B

Voir aussi séquences d'échappement . enter image description here

Il existe un court fichier batch, qui imprime un ensemble de base de caractères spéciaux et leurs séquences d'échappement.

0voto

James Curran Points 55356

L'échappement des parenthèses, comme sous unix, ne fonctionne pas non plus :

echo une chaîne de caractères \< avec des crochets \> >>monfichier.txt

La barre oblique inverse est considérée comme le début d'un nom de chemin absolu.

2 votes

Nom de chemin absolu relatif à la lettre de lecteur actuelle... ;)

0 votes

Une barre oblique inversée n'est pas considérée comme le début d'un nom de chemin absolu dans le texte d'une commande echo -- c'est juste du texte brut qui est acheminé là où vous l'envoyez. -- echo \ par exemple, fonctionne comme prévu. -- Mais oui, le "\" serait un mauvais choix pour un caractère d'échappement de ligne de commande puisque chaque commande/programme nécessitant un chemin ou un nom de fichier devrait être remplacé par `\`.

1 votes

Cette réponse n'offre pas de solution à la question, certes vague, qui se pose.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X