Comment Windows cmd définit-il les noms des variables d'analyse?
Si j'ai couru setcomme suit:
C:\Users\vagrant>SET UNDEFINED=foo
C:\Users\vagrant>SET UNDEFINED
UNDEFINED=foo
C:\Users\vagrant>SET UNDEFINED
Environment variable UNDEFINED not defined
C:\Users\vagrant>SET UNDEFINED | more
UNDEFINED=foo
C:\Users\vagrant>SET UNDEFINED >nul
C:\Users\vagrant>SET UNDEFINED >nul
Environment variable UNDEFINED not defined
C:\Users\vagrant>SET UNDEFINED | more
Environment variable UNDEFINED not defined
C:\Users\vagrant>SET UNDEFINED >nul | more
Environment variable UNDEFINED not defined
C:\Users\vagrant>SET UNDEFINED >nul| more
C:\Users\vagrant>SET UNDEFINED 2>nul | more
C:\Users\vagrant>SET UNDEFINED 2>nul| more
UNDEFINED=foo
Notez que la 2ème commande ci-dessus est SET UNDEFINED , il y a deux espaces suivis. Et SET UNDEFINED >nul , SET UNDEFINED >nul | more, SET UNDEFINED 2>nul | moreavec un espace de plus avant |. Dans ces commandes, setanalysez la variable avec deux espaces supplémentaires. Alors, comment setanalyser les noms de variables. J'ai également trouvé des scripts d'analyse cmd , mais ici comment le nom de la variable est-il tokenisé?
Modifier Le problème se produit lorsque les espaces sont utilisés avant la redirection de fichier. En d'autres termes, ajouter des espaces après la chaîne et rediriger. Exemple: echo foo>bar.txt Les espaces qui précèdent bar.txtsont ajoutés au fichier ainsi que foo .
En voici des exemples:
Exemple:
Résulte en:
Réponses
Lorsque vous ajoutez les espaces supplémentaires, vous indiquez effectivement à set de faire afficher la valeur d'une variable appelée "UNDEFINED "ou %UNDEFINED %qui n'est en fait pas définie. Vous pouvez voir que les espaces ne seront plus un problème si vous faites set "UNDEFINED" avec les espaces après les guillemets doubles. C'est la même chose que faire set UNDEFINED =fooqui ne retournera pas une variable pour %UNDEFINED%bu à la place pour%UNDEFINED %
En voici des exemples:
set UNDEFINED=foo
set UNDEFINED =foo
quand puis exécutez, sans espaces supplémentaires:
set UNDEFINED Le résultat est comme prévu.
UNDEFINED=foo
UNDEFINED =foo
mais lorsque vous l'exécutez avec les espaces supplémentaires, set UNDEFINED le résultat ne correspond plus en %UNDEFINED%raison des espaces supplémentaires que vous avez donnés.
UNDEFINED =foo
Ici, nous pouvons montrer plus comment fonctionne la correspondance
set UNDEF=foo
set UNDEFI=foo
set UNDEFIN=foo
set UNDEFINE=foo
set UNDEFINED=foo
set UNDEFINED =foo
set UNDEFINED =foo
set UNDEFINED =foo
maintenant voir les résultats de tous ces
set UN
set UNDEF
set UNDEFINE
set UNDEFINED
et évidemment en ajoutant les espaces: set UNDEFINED
mais si nous ajoutons 4 espaces, représentant une variable que nous n'avons jamais définie, alors nous obtiendrons un undefinedrésultat de variable.set UNDEFINED
Enfin, pour surmonter cela, il faut s'assurer que nous définissons correctement les variables et que nous les citons deux fois pour obtenir les résultats souhaités.
set "UNDEFINED=foo"
set "UNDEFINED"
La dernière commande set ne se souciera pas du nombre d'espaces que vous donnez après la fin des guillemets doubles, elle renverra toute variable contenant le mot UNDEFINED. c'est à direset "UNDEFINED"
Il en va de même pour les résultats utilisant des redirections >ou des canaux |. Spécifiquement en utilisant la redirection. tout avant le >est considéré comme la chaîne que vous souhaitez rediriger. Exemple:
echo foo >out.txt
Se traduira par out.txtcontenir foo y compris l'espace. Par conséquent, l'exclusion de l'espace est nécessaire, mais cela devient un problème si votre chaîne se termine par un nombre. c'est à dire
echo foo2>out.txt
Ce qui redirigera stderrvers le fichier. Donc, nous surmontons cela à nouveau, en mettant le code entre parenthèses:
(echo foo)>out.txt
Par conséquent, étant donné vos exemples, bien que le piping to nulne renvoie aucun résultat, sauf si vous spécifiez le type (stdout / stderr)
(SET UNDEFINED)2>nul|more
(SET UNDEFINED)1>nul|more
(SET UNDEFINED)>nul|more
ÉDITER
Encore. Des espaces supplémentaires, précédant les chaînes avec des espaces, ajouteront des espaces à la sortie. Encore une fois en utilisantecho
(echo foo | more)>out.txt
Il y a un espace entre fooet |si vous regardez les résultats, out.txtvous remarquerez l'espace. Il en va de même pour la redirection. >D'où les blocs entre parenthèses utilisés dans ces instances pour éliminer les espaces.
EDIT2
Selon les captures d'écran que vous avez fournies. cmdutilise la redirection d'une manière qui ne se soucie pas vraiment de l'endroit où vous la placez.
>out.txt echo foo
aura pour résultat:
foo
dans le fichier. où l'ajout d'espaces, sera ajouté au fichier
>out.txt echo foo aura pour résultat foo
De même que votre exemple, qui fera écho à tout ce que vous donnez dans la ligne de la redirection.
echo foo>out.txt
ou
echo foo>out.txt . ajoutera au fichier car la redirection est vraiment la fonction clé ici où elle ajoutera ce que vous lui donnez.
Vous remarquerez cependant que la redirection seule, puis donner les espaces supplémentaires avant la commande ne fera pas cela. C'est simplement parce que vous demandez au système de rediriger une chaîne vers un fichier où les espaces deviennent alors les séparateurs de commandes. Donc ça:
>out.txt echo foose traduira simplement par uniquement foodans votre fichier de sortie.
Donc ... La meilleure méthode pour nous assurer que nous n'ajoutons pas ces espaces indésirables est de faire: >out.txt(echo foo)
La syntaxe set VARsemble ne tolérer qu'une seule fin SPACE(bien que si elle VARn'est pas définie, le SPACEest inclus dans le message d'erreur :) Environment variable VAR not defined. Cela est même vrai lorsque vous utilisez des guillemets, par conséquent set "VAR"et les set "VAR "deux renvoient la valeur de VAR.
Encore plus étrange est le fait qu'un caractère supplémentaire derrière la fin SPACE, comme dans set VAR Xou set "VAR X", renvoie toujours la valeur de la variable.
Cela est dû à la gestion et à l'analyse spécifiques de la ligne de commande par la setcommande. Je ne peux pas répondre à la question "pourquoi" car je ne suis pas l'un des développeurs de cmd.exe.
Lors de l'utilisation de la redirection (comme dans set VAR > con), l'interpréteur de commandes supprime l'expression de redirection ( > con) à un moment donné (pendant la phase 2, comme décrit dans Comment l'interpréteur de commandes Windows (CMD.EXE) analyse-t-il les scripts? ), Indépendamment de la commande, en laissant le ligne de commande restante, y compris le potentiel SPACEs. Ainsi set VAR > condevient set VAR > con+ SPACE, qui renvoie la valeur de VARquand il est défini, et set VAR > con+ SPACEdevient set VAR+ SPACE+ SPACE, qui échoue à renvoyer la valeur de VAR. De plus echo text> con+ SPACEsmaintient la fuite SPACEsderrière la partie de redirection, qui deviennent alors écho.
Car set, l'utilisation de citations comme set "VAR" > conne se soucie pas du nombre de traînées SPACEset fonctionne donc comme prévu. Pour echo, une option consiste à utiliser des parenthèses comme (echo text) > con, et une autre consiste à déplacer la partie de redirection vers l'avant comme > con echo text(mais évidement en évitant la fin SPACEs).
Jetez un coup d'œil à ce fil de questions-réponses étroitement lié: l' exécution conditionnelle set VAR 2> nuléchoue .