Espaces et parenthèses dans les fenêtres PATH variable coupe les fichiers par lots

Donc, ma variable de chemin (System-> Adv Settings-> Env Vars-> System-> PATH) 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.

Notez les lignes contenant PathWithSpaces – la première n'a pas d'espace, la seconde a un espace et la troisième a un espace suivi d'une parenthèse.

Maintenant, notez la sortie de ce fichier batch:

 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 plus précisément la ligne:

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

Alors, qu'est-ce que cette connerie?

Plus précisément:

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

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, veuillez me le faire savoir 🙂

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

Vous pouvez généralement le réparer en activant l'expansion retardée et utilisez des variables avec !var! Au lieu de %var% . Il n'y a pas beaucoup plus de conseils que je pourrais donner sans voir le code.

Remarque pour les utilisateurs de 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

Il devrait y avoir (a) pas de guillemets dans la variable environnementale MS-Windows PATH (commande PATH) ou (b) il devrait y avoir des guillemets entourant l'expression entière suivant la commande (SET) . Malheureusement, MS 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 (référence de ligne de commande Windows XP) .

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

Cela peut causer des problèmes incohérents et donc difficiles à diagnostiquer. Par exemple, si votre chemin comprend "C: \ Python27", votre machine dira que "'python' n'est pas reconnu comme une commande interne ou externe, un programme opérationnel ou un fichier batch." Lorsque vous essayez d'exécuter python. DdddddélbeAachésacheaúdachachachetachachachachetachachachetachachachistándeterméliedicedéleterdeterdeterádiceadd

Vous n'avez pas besoin de "échapper" les espaces ou les parenthèses. Si vous devez échapper à des caractères spéciaux, mettez des devis autour de l'expression entière, y compris le nom de la variable.

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

Trap Da Marco Da Marco citadin Tram Da Marco Da Marco Da Marco Da Marco citadin TramemetéesAélierem av afea aleeadiceddice

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

Remarque, les guillemets doivent être par paires.

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

Cependant, il n'y a probablement pas de caractères qui sont des chemins d'accès valides, ce qui causerait un problème avec la commande SET.

Microsoft documente le problème dans " Erreur lors de l'exécution des scripts shell de commande 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 devriez 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 d'autres variables, une autre solution peut être d'utiliser des citations, mais autour de tout:

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

Joey dans sa réponse dit

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

et c'est vrai. S'il y a des parenthèses non définies, il faut les é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.

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

Fondamentalement, au lieu de changer la variable Path via System-> Adv Settings-> Env Vars-> System-> PATH, try

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

Dans Windows 8, j'ai trouvé très peu de succès avec l'une de ces méthodes. Les parenthèses ne fonctionnent pas, les citations 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 encore utiliser le chemin du 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 si on les ajoute temporairement, cela fonctionnera car je n'en ai besoin que pendant le fonctionnement d'un fichier de commandes. Mais cela ne fonctionne même pas.

echo %path% affiche le système PATH au moment où le cmd été lancé.

set path="%path%;%programfiles(x86)%\company\program\subdir" fonctionne mais maintenant %path% contient tout entouré de guillemets, et si j'essaie d'exécuter un programme en sous-programme d'un autre endroit, il échoue. L'utilisation de parenthèses autour du tout au lieu des guillemets ne fonctionne pas .

Une autre chose que j'ai remarquée, c'est que la même commande fonctionnera si elle est entrée de manière interactive dans cmd , mais pas si elle se trouve dans un fichier batch. C'est effrayant. Encore une autre bizarrerie est la perte intermittente du dernier caractère de la valeur d'une variable d'environnement! Une autre incompatibilité avec les programmes tiers: certains peuvent gérer un %var% tant que paramètre, d'autres ne le font pas.

J'ai eu énormément de difficulté à faire les travaux suivants dans Win8 jusqu'à ce que j'ai ajouté des doubles guillemets autour de la valeur que je réglais sur la variable fromFile. En dehors de cela, lorsque FromFile contenait un nom de fichier avec des parenthèses, la ligne suivante qui essayait de faire la substitution de chaîne pour générer la variable toFile était en panne. Notez que j'utilise une extension retardée pour évaluer la variable au moment de l'exécution au lieu de l'heure 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