web-dev-qa-db-fra.com

Espaces et parenthèses dans Windows PATH variable visse les fichiers de commandes

Ainsi, ma variable de chemin (Système-> Paramètres avancés-> Env Vars-> Système-> CHEMIN) est définie sur:

C:\Python26\Lib\site-packages\PyQt4\bin;
%SystemRoot%\system32;
%SystemRoot%;
%SystemRoot%\System32\Wbem;
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;
C:\Python26\;
C:\Python26\Scripts\;
C:\cygwin\bin;
"C:\PathWithSpaces\What_is_this_bullshit";
"C:\PathWithSpaces 1.5\What_is_this_bullshit_1.5";
"C:\PathWithSpaces (2.0)\What_is_this_bullshit_2.0";
"C:\Program Files (x86)\IronPython 2.6";
"C:\Program Files (x86)\Subversion\bin";
"C:\Program Files (x86)\Git\cmd";
"C:\Program Files (x86)\PuTTY";
"C:\Program Files (x86)\Mercurial";
Z:\droid\Android-sdk-windows\tools;

Bien que, évidemment, sans les nouvelles lignes.

Remarquez les lignes contenant PathWithSpaces - la première n'a pas d'espaces, la seconde a une espace et la troisième a une espace suivie d'une parenthèse.

Notez maintenant la sortie de ce fichier de commandes:

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\>vcvars32.bat
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>"C:\Program Files (x86
)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
\What_is_this_bullshit_2.0";"C:\Program was unexpected at this time.
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>      set "PATH=C:\Pro
gram Files\Microsoft SDKs\Windows\v6.0A\bin;C:\Python26\Lib\site-packages\PyQt4\
bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\
WindowsPowerShell\v1.0\;C:\Python26\;C:\Python26\Scripts\;C:\cygwin\bin;"C:\Path
WithSpaces\What_is_this_bullshit";"C:\PathWithSpaces 1.5\What_is_this_bullshit_1
.5";"C:\PathWithSpaces (2.0)\What_is_this_bullshit_2.0";"C:\Program Files (x86)\
IronPython 2.6";"C:\Program Files (x86)\Subversion\bin";"C:\Program Files (x86)\
Git\cmd";"C:\Program Files (x86)\PuTTY";"C:\Program Files (x86)\Mercurial";Z:\dr
oid\Android-sdk-windows\tools;"

ou spécifiquement la ligne:

\What_is_this_bullshit_2.0";"C:\Program was unexpected at this time.

Alors, quelle est cette connerie?

Plus précisément:

  • Répertoire dans le chemin échappé correctement avec des guillemets, mais sans espaces = fin
  • Répertoire dans le chemin qui est correctement échappé avec des guillemets et qui contient des espaces mais pas de parenthèse = fin
  • Répertoire dans le chemin échappé correctement avec des guillemets, avec des espaces et une parenthèse = ERROR

Que se passe t-il ici? Comment puis-je réparer cela? Je vais probablement recourir à un point de jonction pour laisser mes outils fonctionner toujours comme solution de contournement, mais si vous avez un aperçu de cela, merci de me le faire savoir :)

14
user30404

Cela peut se produire s'il y a des parenthèses non échappées dans une ligne à l'intérieur d'un "bloc" (qui utilise également des parenthèses pour la délimitation).

Vous pouvez généralement résoudre ce problème en activant l’extension différée et en utilisant des variables avec !var! au lieu de %var%. Je ne pourrais pas donner beaucoup plus de conseils sans voir le code.

12
Joey

Remarque pour les utilisateurs Windows sur les systèmes 64 bits

Progra ~ 1 = 'Program Files' Progra ~ 2 = 'Program Files (x86)'

https://confluence.atlassian.com/display/DOC/Setting+the+Java_HOME+Variable+in+Windows

18
Robb

Il ne devrait y avoir (a) pas de guillemets dans la variable d’environnement PATH de MS-Windows (commande PATH) ou (b) il devrait y avoir des guillemets entourant l'expression entière après le signe (commande SET) . Malheureusement, ceci n’est pas très bien documenté par MS, bien qu’ils indiquent que si des guillemets sont utilisés, ils seront inclus dans la valeur de la variable (Windows XP Command Ligne de référence) .

$ SET BLAH="blah blah(1)"
$ ECHO %BLAH%
"blah blah(1)"
$ SET BLAH=blah blah(1)
$ ECHO %BLAH%
blah blah(1)

Cela peut entraîner des problèmes incohérents et donc difficiles à diagnostiquer. Par exemple, si votre chemin inclut "C:\Python27", votre machine indiquera que "" python "n'est pas reconnu en tant que commande interne ou externe, programme utilisable ou fichier de commandes." lorsque vous essayez d'exécuter Python. Cependant, certaines bibliothèques peuvent rester disponibles.

Vous ( pas ne devez "échapper" ni aux espaces ni aux parenthèses. Si vous devez échapper des caractères spéciaux, mettez des guillemets autour de l'expression entière , y compris le nom de la variable.

SET "PATH=%PATH%;C:\Program Files (x86)\path with special characters"

ou vous pouvez aussi utiliser des parenthèses.

(SET VAR=can't contain ampersand, parentheses, pipe, gt or lt)

Notez que les guillemets doubles doivent venir par paires.

(SET VAR=illegal characters!@#$%^*_-+={}[]\:;""',./?)
echo %VAR%
illegal characters!@#$%*_-+={}[]\:;""',./?

Cependant, il n'y a probablement aucun caractère qui soit un chemin d'accès valide, ce qui poserait un problème avec la commande SET.

13
Mark Mikofski

Microsoft documente le problème dans " Erreur lors de l'exécution de scripts de commandes shell incluant des parenthèses ".

La solution qu'ils suggèrent est d'utiliser une expansion retardée.

SETLOCAL ENABLEDELAYEDEXPANSION
SET VAR=string containing ( and ) ...
IF "y" == "y" (
    ECHO !VAR! %VAR%
)
ENDLOCAL

Pour définir un chemin dans un bloc if, plutôt que d'utiliser SET PATH=, vous devez probablement utiliser la commande PATH.

SET AddToPath=C:\Program Files (x86)\Whatever

SETLOCAL ENABLEDELAYEDEXPANSION
IF "%X%" == "%Y%" (
    ECHO Adding !AddToPath! to path !PATH!
    PATH !AddToPath!;!PATH!
)

Pour les autres variables, une autre solution consiste à utiliser des guillemets, mais en gros:

SET "MyVar=C:\Program Files (x86)\Whatever"
2
mivk

Sous Windows 8, aucune de ces méthodes n’a eu beaucoup de succès. Les parenthèses ne fonctionnent pas, les guillemets fonctionnent, mais le "chemin" que vous modifiez de cette façon n'est pas le chemin utilisé pour localiser les exécutables, mais cmd semble toujours utiliser le chemin système qu'il a hérité lorsque vous avez ouvert la fenêtre.

exemple: après avoir déterminé l'architecture du processeur, je souhaite ajouter quelques chemins à la variable d'environnement PATH. En fait, même simplement les ajouter temporairement fonctionnerait puisque je n’en ai besoin que pendant l’exécution d’un fichier de commandes. Mais ça ne marche même pas.

echo %path% affiche le système PATH au moment du lancement de la cmd.

set path="%path%;%programfiles(x86)%\company\program\subdir" fonctionne, mais maintenant %path% contient tout ce qui est entouré de guillemets. Si j'essaie d'exécuter un programme dans subdir ailleurs, il échoue. L'utilisation de parenthèses au lieu de guillemets ne fonctionne pas .

Une autre chose que j'ai remarquée est que la même commande fonctionnera si elle est entrée de manière interactive dans cmd, mais pas si elle est rencontrée dans un fichier de traitement par lots. C'est effrayant. Une autre bizarrerie est la perte intermittente du dernier caractère de la valeur d'une variable d'environnement! Une autre incohérence concerne les programmes tiers: certains peuvent gérer un %var% en tant que paramètre, d’autres pas.

1
Pete

Joey dans sa réponse dit

Cela peut se produire s'il y a des parenthèses non échappées dans une ligne à l'intérieur d'un "bloc" (qui utilise également des parenthèses pour la délimitation).

et c'est vrai. S'il y a des parenthèses non échappées, il faut bien leur échapper. C'est ce que j'ai fait; j'ai remplacé

set PATH=some_path;%PATH%

avec

set PATH="some_path;%PATH%"

et cela a résolu le problème.

1
Piotr Dobrogost

J'ai vécu quelque chose de similaire. Microsoft explique le problème ici: http://support.Microsoft.com/kb/329308

En gros, au lieu de changer la variable Path via System-> Adv Settings-> Env Vars-> System-> PATH, essayez

My Computer->Manage->Computer Management (local)-> Properties-> Advanced-> Environment variables-> Settings
1
phearce

J'ai eu beaucoup de mal à faire le travail suivant dans Win8 jusqu'à ce que j'ajoute des guillemets autour de la valeur que je définissais à la variable fromFile. Sans cela, lorsque fromFile contenait un nom de fichier avec des parenthèses, la ligne suivante qui tentait d'effectuer une substitution de chaîne pour générer la variable toFile échouait. Notez que j'utilise le développement retardé pour évaluer la variable au moment de l'exécution au lieu du moment de l'analyse (de l'instance CALL respective)

::-- BATCH file that creates an *_576_5.* file from an *_640_t.* one (copying it)
::-- Author: George Birbilis (http://zoomicon.com)
::-- Credits: String replacement based on http://www.dostips.com/DtTipsStringManipulation.php

@ECHO OFF

::-- Loop for all files recursively --::

FOR /R %%f in (*_640_t.*) DO CALL :process %%f

ECHO(
PAUSE

GOTO :EOF

::-- Per-file actions --::

:process

:: Display progress...
::ECHO Processing %*
<nul (set/p dummy=.)

SETLOCAL ENABLEDELAYEDEXPANSION
SET fromFile="%*"
SET toFile=!fromFile:_640_t=_576_t!

IF NOT EXIST %toFile% CALL :generate %fromFile% %toFile%

GOTO :EOF

::-- Generate missing file --::

:generate

ECHO(
ECHO COPY %*
COPY %*

::PAUSE

GOTO :EOF
1
George Birbilis