Comment appeler un sous-programme dont le paramètre est une variable contenant une esperluette (& amp;)?
Il n'y a pas d'erreur, mais l'appel ne semble jamais s'exécuter.
exemple.bat
@echo off
setlocal enableDelayedExpansion
rem Doesn't work
set val=with^&ersand
call :Output !val!
rem Works fine
set val=without_ampersand
call :Output !val!
goto End
:Output
set "line=%1"
echo Called: !line!
goto :eof
End:
Sortie:
Appelé: without_ampersand
Modifier:
L'utilisation de Expansion retardée n'est pas requis. C'était juste utilisé dans cet exemple. Une façon de le faire sans utiliser delayExpansion est préférable.
La question se concentre sur "Comment appeler" plutôt que "Comment définir initialement la variable". La variable peut provenir d'une entrée utilisateur ou d'un for /f
boucle (comme c'est mon cas).
windows
batch-file
ANisus
la source
la source
^
. Mais cela ne transmettra pas la valeur au sous-programme.set val=with^^^&ersand
donc beaucoup plus échapper.Réponses:
Les règles d’échappement par lots sont plutôt désagréables, mais le comportement est totalement prévisible si vous connaissez les règles.
L'information dont vous avez besoin pour comprendre le problème est disponible à l'adresse Comment le Windows Command Interpreter (CMD.EXE) analyse-t-il les scripts? dans les phases 1, 2, 5 et 6 de la réponse acceptée. Mais bonne chance pour absorber cette information à tout moment :-)
Deux problèmes de conception fondamentaux sont à l'origine de votre problème: - La phase 6 double tous les carets, ce qui relance ensuite la phase 2 (en réalité les phases 1, 1.5 et 2). - Mais la phase 2 nécessite
&
être échappé comme^&
. Notez que ce doit être un seul^
, pas doublé!La seule façon d’obtenir votre approche au travail est d’introduire le
^
après la phase 6, le nombre de caret a doublé.ESC est défini pour tenir
^
.Le premier tour de la phase 1 se développe
%%ESC%%
à%ESC%
le second tour de la phase 1 (initié par la phase 6) se développe
%ESC%
à^
Tout cela est totalement irréalisable, surtout si vous ne savez pas ce que le contenu va être.
La seule stratégie sensée pour passer de manière fiable une valeur dans une routine CALLed consiste à passer par référence. Transmettez le nom d'une variable contenant la valeur de chaîne et développez cette valeur dans votre sous-routine à l'aide de l'expansion retardée.
la source
Si vous ajoutez un supplément
^
et guillemets ça va marcher:SET LOCAL EnableDelayedExpansion
nécessite 2 caractères d'échappement:ECHO 123 ^^& 456^^!
va sortir123 & 456!
.Vous devriez aussi utiliser
SET
toujours avec des guillemets!la source
set val=!val:^&=^^^^^&!
) avant l'appel? Cela ne semble pas fonctionner.&
combiné aveccall
Là? Si tel est le cas, vous pouvez éditer la variable et remplacer le&
avec quelque chose d'autre que vous remplacez à nouveau par un&
plus tard. Ou vous utilisez simplement le motand
(si c'est le but de la&
ici).