Comment vérifier si le répertoire existe dans %PATH%?
Comment vérifier si un répertoire est déjà présent dans la variable d'environnement PATH? Voici un début. Tout ce que j'ai réussi à faire avec le code ci-dessous, c'est echo le premier répertoire dans %PATH%. Comme il s'agit d'une boucle FOR, on pourrait penser qu'elle énumérerait tous les répertoires dans %PATH%, mais elle n'obtient que le premier.
y a-t-il une meilleure façon de faire cela? Quelque chose comme find ou findstr opérant sur la variable %PATH%? Je voudrais juste vérifier si un répertoire existe dans la liste des répertoires dans %PATH%, pour éviter d'ajouter quelque chose qui pourrait déjà être là.
FOR /F "delims=;" %%P IN ("%PATH%") DO (
@ECHO %%~P
)
21 réponses
tout d'abord, je vais souligner un certain nombre de questions qui rendent ce problème difficile à résoudre parfaitement. Alors je présenterai la solution la plus pare-balles que j'ai pu trouver.
pour cette discussion, j'utiliserai le chemin en minuscules pour représenter un chemin de dossier unique dans le système de fichiers, et le chemin en majuscules pour représenter la variable D'environnement de chemin.
d'un point de vue pratique, la plupart des gens veulent savoir si le chemin contient le l'équivalent logique d'un chemin donné, pas si le chemin contient une correspondance exacte d'un chemin donné. Cela peut être problématique parce que:
-
le
\
est facultatif dans un chemin d'accès
La plupart des chemins fonctionnent aussi bien avec que sans le\
. Le chemin indique logiquement le même endroit de toute façon. Le chemin a souvent un mélange de chemins à la fois avec et sans le\
. C'est probablement la question pratique la plus courante lors de la recherche d'un chemin pour une correspondance.- il y a une exception: le chemin relatif
C:
(qui signifie le répertoire courant du lecteur C) est très différent deC:\
(qui signifie le répertoire racine du lecteur C).)
- il y a une exception: le chemin relatif
-
certains sentiers ont autres noms abrégés
Tout chemin qui ne répond pas à l'ancienne norme 8.3 a une forme courte alternative qui répond à la norme. Il s'agit d'une autre question de cheminement que j'ai rencontrée avec une certaine fréquence, particulièrement dans les milieux d'affaires. -
Windows accepte à la fois
/
et\
comme séparateurs de dossiers dans un chemin.
Ce n'est pas très souvent, mais un chemin peut être spécifié en utilisant/
au lieu de\
et il fonctionnera très bien dans le chemin (ainsi que dans de nombreux autres contextes Windows) -
Windows traite les séparateurs de dossiers consécutifs comme un séparateur logique.
C:\FOLDER et C:\FOLDER sont équivalents. Cela aide en fait dans de nombreux contextes lors de la gestion d'un chemin parce qu'un développeur peut généralement ajouter\
à un chemin sans prendre la peine de vérifier si le\
existe déjà. Mais cela peut évidemment causer des problèmes si vous essayez d'effectuer une correspondance exacte.- Exceptions: non seulement
C:
, différent deC:\
, maisC:\
(un chemin valide), est différent deC:\
(un chemin invalide).
- Exceptions: non seulement
-
Windows trims suit des points et des espaces à partir de noms de fichiers et de répertoires.
"C:\test. "
est l'équivalent de"C:\test"
. -
L'actuel
.\
et les parents..\
dossier prescripteurs peuvent apparaître à l'intérieur d'un chemin
Peu probable d'être vu dans la vraie vie, mais quelque chose commeC:\.\parent\child\..\.\child\
est équivalent àC:\parent\child
-
un chemin peut être inclus dans des guillemets doubles.
Un chemin est souvent enfermé dans des guillemets pour se protéger contre des caractères spéciaux comme<space>
,
;
^
&
=
. En fait, n'importe quel nombre de citations peut apparaître avant, à l'intérieur et/ou après le chemin. Ils sont ignorés par Windows, sauf dans le but de protéger contre les caractère. Les guillemets ne sont jamais requis à L'intérieur du chemin à moins qu'un chemin ne contienne un;
, mais les guillemets peuvent être présents à tout moment. -
un sillon peut être entièrement qualifié ou relatif.
Un chemin entièrement qualifié indique exactement un emplacement précis dans le système de fichiers. Un chemin relatif change selon la valeur des volumes de travail et des répertoires courants. Il y a trois saveurs primaires des chemins relatifs:-
D:
est relatif à l'annuaire courant du volume D: -
\myPath
est relatif au volume de travail actuel (pourrait être C:, D: etc.) -
myPath
est relatif au volume de travail actuel et à l'annuaire
Il est parfaitement légal d'inclure un chemin relatif dans le chemin. C'est très courant dans le monde Unix car Unix ne Recherche pas le répertoire courant par défaut, de sorte qu'un chemin Unix contiendra souvent
.\
. Mais Windows recherche le répertoire courant par défaut, donc les chemins relatifs sont rares dans un chemin Windows. -
ainsi, pour vérifier de manière fiable si le chemin contient déjà un chemin, nous avons besoin d'un moyen de convertir n'importe quel chemin donné en un canonique (standard) forme. Le modificateur ~s
utilisé par pour l'extension des variables et des arguments est une méthode simple qui aborde les questions 1 à 6, et en partie la question 7. Le modificateur ~s
supprime les guillemets, mais préserve les guillemets internes. La question 7 peut être entièrement résolue en retirant explicitement les citations de tous les chemins avant la comparaison. Notez que si un chemin n'existe pas physiquement, le modificateur ~s
n'ajoutera pas le \
au chemin, ni ne convertira le chemin. dans un format valide de 8.3.
le problème avec ~s
est qu'il convertit les trajectoires relatives en trajectoires entièrement qualifiées. Cela pose problème pour la question 8, car un chemin relatif ne devrait jamais correspondre à un chemin entièrement qualifié. Nous pouvons utiliser les expressions régulières de FINDSTR pour classer un chemin soit comme entièrement qualifié, soit comme relatif. Un parcours normal entièrement qualifié doit commencer par <letter>:<separator>
mais pas par <letter>:<separator><separator>
, où \
soit /
. Les chemins de L'UNC sont toujours pleinement qualifié et doit commencer par \
. Lorsque nous comparons des parcours entièrement qualifiés, nous utilisons le modificateur ~s
. Lorsque nous comparons les chemins relatifs, nous utilisons les chaînes brutes. Enfin, nous ne comparons jamais un parcours entièrement qualifié à un parcours relatif. Cette stratégie offre une bonne solution pratique à la question 8. La seule limitation est que deux chemins relatifs logiquement équivalents pourraient être traités comme ne pas correspondre, mais c'est une préoccupation mineure car les chemins relatifs sont rares dans un chemin Windows.
il y a d'autres questions qui compliquent ce problème:
9) Normal extension n'est pas fiable lorsque vous traitez avec un CHEMIN d'accès contient des caractères spéciaux.
Les caractères spéciaux n'ont pas besoin d'être cités dans PATH, mais ils pourraient l'être. Donc un chemin comme
C:\THIS & THAT;"C:\& THE OTHER THING"
est parfaitement valide, mais il ne peut pas être étendu en toute sécurité en utilisant une expansion simple parce que les deux "%PATH%"
et %PATH%
échouera.
10) le délimiteur de chemin est également valide dans un nom de chemin
Un ;
est utilisé pour délimiter les chemins de CHEMIN, mais ;
peut aussi être un caractère valide dans un chemin, auquel cas le chemin d'accès doit être cité. Cela provoque un problème d'analyse.
jeb résolu les deux les questions 9 et 10 à "Pretty print" windows variable %PATH% - comment diviser le ';' dans CMD shell
pour que nous puissions combiner le modificateur ~s
et les techniques de classification du chemin avec ma variation de l'analyseur de chemin de jeb pour obtenir cette solution presque à l'épreuve des balles pour vérifier si un chemin donné existe déjà dans le chemin. La fonction peut être incluse et appelée à partir d'un fichier batch, ou elle peut être autonome et être appelée comme son propre inPath.bat fichier de commandes. Il semble que beaucoup de code, mais plus de la moitié est des commentaires.
@echo off
:inPath pathVar
::
:: Tests if the path stored within variable pathVar exists within PATH.
::
:: The result is returned as the ERRORLEVEL:
:: 0 if the pathVar path is found in PATH.
:: 1 if the pathVar path is not found in PATH.
:: 2 if pathVar is missing or undefined or if PATH is undefined.
::
:: If the pathVar path is fully qualified, then it is logically compared
:: to each fully qualified path within PATH. The path strings don't have
:: to match exactly, they just need to be logically equivalent.
::
:: If the pathVar path is relative, then it is strictly compared to each
:: relative path within PATH. Case differences and double quotes are
:: ignored, but otherwise the path strings must match exactly.
::
::------------------------------------------------------------------------
::
:: Error checking
if "%~1"=="" exit /b 2
if not defined %~1 exit /b 2
if not defined path exit /b 2
::
:: Prepare to safely parse PATH into individual paths
setlocal DisableDelayedExpansion
set "var=%path:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
set "var=!var:"S"S=";"!"
::
:: Remove quotes from pathVar and abort if it becomes empty
set "new=!%~1:"=!"
if not defined new exit /b 2
::
:: Determine if pathVar is fully qualified
echo("!new!"|findstr /i /r /c:^"^^\"[a-zA-Z]:[\/][^\/]" ^
/c:^"^^\"[\][\]" >nul ^
&& set "abs=1" || set "abs=0"
::
:: For each path in PATH, check if path is fully qualified and then do
:: proper comparison with pathVar.
:: Exit with ERRORLEVEL 0 if a match is found.
:: Delayed expansion must be disabled when expanding FOR variables
:: just in case the value contains !
for %%A in ("!new!\") do for %%B in ("!var!") do (
if "!!"=="" endlocal
for %%C in ("%%~B\") do (
echo(%%B|findstr /i /r /c:^"^^\"[a-zA-Z]:[\/][^\/]" ^
/c:^"^^\"[\][\]" >nul ^
&& (if %abs%==1 if /i "%%~sA"=="%%~sC" exit /b 0) ^
|| (if %abs%==0 if /i "%%~A"=="%%~C" exit /b 0)
)
)
:: No match was found so exit with ERRORLEVEL 1
exit /b 1
la fonction peut être utilisée comme so (en supposant que le fichier batch s'appelle inPath.chauve-souris):
set test=c:\mypath
call inPath test && (echo found) || (echo not found)
Typiquement la raison pour vérifier si un chemin existe dans le chemin est parce que vous voulez ajouter le chemin s'il n'est pas là. Ceci est normalement fait simplement en utilisant quelque chose comme
path %path%;%newPath%
. Mais le numéro 9 montre à quel point cela n'est pas fiable.
un autre problème est comment retourner la valeur du chemin final à travers la barrière ENDLOCAL à la fin de la fonction, surtout si la fonction peut être appelée avec une extension retardée activée ou désactivée. N'importe quel !
non enregistré corrompra la valeur si l'expansion retardée est activée.
ces problèmes sont résolus en utilisant une étonnante technique de retour sûr que jeb a inventé ici: http://www.dostips.com/forum/viewtopic.php?p=6930#p6930
@echo off
:addPath pathVar /B
::
:: Safely appends the path contained within variable pathVar to the end
:: of PATH if and only if the path does not already exist within PATH.
::
:: If the case insensitive /B option is specified, then the path is
:: inserted into the front (Beginning) of PATH instead.
::
:: If the pathVar path is fully qualified, then it is logically compared
:: to each fully qualified path within PATH. The path strings are
:: considered a match if they are logically equivalent.
::
:: If the pathVar path is relative, then it is strictly compared to each
:: relative path within PATH. Case differences and double quotes are
:: ignored, but otherwise the path strings must match exactly.
::
:: Before appending the pathVar path, all double quotes are stripped, and
:: then the path is enclosed in double quotes if and only if the path
:: contains at least one semicolon.
::
:: addPath aborts with ERRORLEVEL 2 if pathVar is missing or undefined
:: or if PATH is undefined.
::
::------------------------------------------------------------------------
::
:: Error checking
if "%~1"=="" exit /b 2
if not defined %~1 exit /b 2
if not defined path exit /b 2
::
:: Determine if function was called while delayed expansion was enabled
setlocal
set "NotDelayed=!"
::
:: Prepare to safely parse PATH into individual paths
setlocal DisableDelayedExpansion
set "var=%path:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
set "var=!var:"S"S=";"!"
::
:: Remove quotes from pathVar and abort if it becomes empty
set "new=!%~1:"^=!"
if not defined new exit /b 2
::
:: Determine if pathVar is fully qualified
echo("!new!"|findstr /i /r /c:^"^^\"[a-zA-Z]:[\/][^\/]" ^
/c:^"^^\"[\][\]" >nul ^
&& set "abs=1" || set "abs=0"
::
:: For each path in PATH, check if path is fully qualified and then
:: do proper comparison with pathVar. Exit if a match is found.
:: Delayed expansion must be disabled when expanding FOR variables
:: just in case the value contains !
for %%A in ("!new!\") do for %%B in ("!var!") do (
if "!!"=="" setlocal disableDelayedExpansion
for %%C in ("%%~B\") do (
echo(%%B|findstr /i /r /c:^"^^\"[a-zA-Z]:[\/][^\/]" ^
/c:^"^^\"[\][\]" >nul ^
&& (if %abs%==1 if /i "%%~sA"=="%%~sC" exit /b 0) ^
|| (if %abs%==0 if /i %%A==%%C exit /b 0)
)
)
::
:: Build the modified PATH, enclosing the added path in quotes
:: only if it contains ;
setlocal enableDelayedExpansion
if "!new:;=!" neq "!new!" set new="!new!"
if /i "%~2"=="/B" (set "rtn=!new!;!path!") else set "rtn=!path!;!new!"
::
:: rtn now contains the modified PATH. We need to safely pass the
:: value accross the ENDLOCAL barrier
::
:: Make rtn safe for assignment using normal expansion by replacing
:: % and " with not yet defined FOR variables
set "rtn=!rtn:%%=%%A!"
set "rtn=!rtn:"=%%B!"
::
:: Escape ^ and ! if function was called while delayed expansion was enabled.
:: The trailing ! in the second assignment is critical and must not be removed.
if not defined NotDelayed set "rtn=!rtn:^=^^^^!"
if not defined NotDelayed set "rtn=%rtn:!=^^^!%" !
::
:: Pass the rtn value accross the ENDLOCAL barrier using FOR variables to
:: restore the % and " characters. Again the trailing ! is critical.
for /f "usebackq tokens=1,2" %%A in ('%%^ ^"') do (
endlocal & endlocal & endlocal & endlocal & endlocal
set "path=%rtn%" !
)
exit /b 0
Je n'ai pas fait de programmation de fichiers par lots depuis un moment, mais:
echo ;%PATH%; | find /C /I ";<string>;"
devrait vous donner 0 si la chaîne n'est pas trouvée et 1 ou plus si elle est.
EDIT: ajout d'un drapeau insensible à la casse, grâce à Panos.
une autre façon de vérifier si quelque chose est dans le chemin est d'exécuter un exécutable innocent qui ne va pas échouer s'il est là, et vérifier le résultat. Par exemple, l'extrait de code suivant vérifie si maven est dans le chemin:
mvn --help > NUL 2> NUL
if errorlevel 1 goto mvnNotInPath
donc j'essaie d'exécuter mvn --aide , ignorer la sortie (ne veulent pas réellement voir l'aide si maven est là) (>NUL), et aussi ne pas afficher le message d'erreur si maven n'était pas trouvé (2 > NUL).
après avoir lu les réponses ici je pense que je peux fournir un nouveau point de vue: si le but de cette question Est de savoir si le chemin vers un certain fichier exécutable existe dans %PATH%
et si non, l'insérer (et c'est la seule raison pour faire cela, je pense), alors il peut résolu d'une manière légèrement différente: "Comment vérifier si le répertoire d'un certain programme exécutable existe en %PATH%"? Cette question peut être facilement résolue de cette façon:
for %%p in (programname.exe) do set "progpath=%%~$PATH:p"
if not defined progpath (
rem The path to programname.exe don't exist in PATH variable, insert it:
set "PATH=%PATH%;C:\path\to\progranname"
)
si vous ne connaissez pas l'extension du fichier exécutable, examinez-les tous:
set "progpath="
for %%e in (%PATHEXT%) do (
if not defined progpath (
for %%p in (programname.%%e) do set "progpath=%%~$PATH:p"
)
)
par for
et delims
, vous ne pouvez pas capturer un nombre arbitraire de champs (comme Adam a souligné aussi) donc vous devez utiliser une technique de boucle à la place. Le script de commande suivant listera chaque chemin dans la variable d'environnement PATH
sur une ligne séparée:
@echo off
setlocal
if "%~1"=="" (
set PATHQ=%PATH%
) else (
set PATHQ=%~1 )
:WHILE
if "%PATHQ%"=="" goto WEND
for /F "delims=;" %%i in ("%PATHQ%") do echo %%i
for /F "delims=; tokens=1,*" %%i in ("%PATHQ%") do set PATHQ=%%j
goto WHILE
:WEND
il simule un classique tandis que ... wend construit trouvé dans de nombreux langages de programmation.
Avec ceci en place, vous pouvez utiliser quelque chose comme findstr
pour ensuite filtrer et chercher un chemin particulier. Par exemple, si vous avez sauvegardé le script ci-dessus dans un fichier appelé tidypath.cmd
alors voici comment vous pouvez pipe à findstr
, à la recherche de chemins sous le répertoire de programmes standard (en utilisant une correspondance non sensible à la casse):
> tidypath | findstr /i "%ProgramFiles%"
cela va chercher une correspondance exacte mais insensible à la casse, alors faites attention à tout slash arrière arrière etc.:
for %P in ("%path:;=";"%") do @if /i %P=="PATH_TO_CHECK" echo %P exists in PATH
ou, dans un fichier discontinu (par exemple checkpath.bat) qui prend un argument:
@for %%P in ("%path:;=";"%") do @if /i %%P=="%~1" echo %%P exists in PATH
sous cette dernière forme, on pourrait appeler par exemple checkpath "%ProgramFiles%"
pour voir si le chemin spécifié existe déjà dans le chemin.
veuillez noter que cette implémentation suppose qu'aucun point-virgule Ou guillemets n'est présent à l'intérieur d'un seul chemin article.
j'ai pris votre implémentation en utilisant la boucle pour et je l'ai étendue en quelque chose qui itère à travers tous les éléments du chemin. Chaque itération de la boucle for supprime le premier élément du chemin (%p) du chemin entier (contenu dans %q et %r).
@echo off
SET MYPATHCOPY=%PATH%
:search
for /f "delims=; tokens=1,2*" %%p in ("%MYPATHCOPY%") do (
@echo %%~p
SET MYPATHCOPY=%%~q;%%~r
)
if "%MYPATHCOPY%"==";" goto done;
goto search;
:done
sortie de L'échantillon:
Z:\>path.bat
C:\Program Files\Microsoft DirectX SDK (November 2007)\Utilities\Bin\x86
c:\program files\imagemagick-6.3.4-q16
C:\WINDOWS\system32
C:\WINDOWS
C:\SFU\common\
c:\Program Files\Debugging Tools for Windows
C:\Program Files\Nmap
Ajouter un répertoire au chemin s'il n'existe pas déjà:
set myPath=c:\mypath
For /F "Delims=" %%I In ('echo %PATH% ^| find /C /I "%myPath%"') Do set pathExists=%%I 2>Nul
If %pathExists%==0 (set PATH=%myPath%;%PATH%)
vous pouvez également utiliser le remplacement de substrat pour tester la présence d'un substrat. Ici, j'ai supprimer les guillemets pour créer PATH_NQ, puis-je supprimer "c:\mydir" à partir de la PATH_NQ et de la comparer à l'original pour voir si quelque chose a changé:
set PATH_NQ=%PATH:"=%
if not "%PATH_NQ%"=="%PATH_NQ:c:\mydir=%" goto already_in_path
set PATH=%PATH%;c:\mydir
:already_in_path
j'ai combiné quelques-unes des réponses ci-dessus pour trouver ceci afin de m'assurer qu'une entrée de chemin donnée existe exactement comme indiqué avec autant de brièveté que possible et pas d'échos indésirables sur la ligne de commande.
set myPath=<pathToEnsure | %1>
echo ;%PATH%; | find /C /I ";%myPath%;" >nul
if %ERRORLEVEL% NEQ 0 set PATH=%PATH%;%myPath%
si votre question était " pourquoi ce fragment de script cmd ne fonctionne-t-il pas?"alors la réponse est que for /f
itère sur les lignes. Le delims
divise les lignes en champs, mais vous capturez seulement le premier champ dans %%P
. Il n'y a aucun moyen de capturer un nombre arbitraire de champs avec une boucle for /f
.
en vous basant sur la réponse de rcar, vous devez vous assurer qu'une sous-couche de la cible n'est pas trouvée.
if a%X%==a%PATH% echo %X% is in PATH
echo %PATH% | find /c /i ";%X%"
if errorlevel 1 echo %X% is in PATH
echo %PATH% | find /c /i "%X%;"
if errorlevel 1 echo %X% is in PATH
vous mentionnez que vous voulez éviter d'ajouter le répertoire au chemin de recherche s'il y existe déjà. Avez-vous l'intention de stocker le répertoire de façon permanente sur le chemin, ou juste temporairement pour le fichier batch?
si vous souhaitez ajouter (ou supprimer) des répertoires de façon permanente sur le chemin, jetez un coup d'oeil sur le Gestionnaire de chemin (pathman.exe) de l'utilitaire de Windows Outils du Kit de Ressources pour les tâches administratives, http://support.microsoft.com/kb/927229 . Avec qui vous peut ajouter ou supprimer des composants du système et des chemins d'utilisateur, et il traitera les anomalies telles que les entrées en double.
si vous devez modifier le chemin seulement temporairement pour un fichier batch, je voudrais juste ajouter le chemin supplémentaire devant le chemin, avec le risque de légère performance frappé en raison de l'entrée en double dans le chemin.
cette version fonctionne assez bien. Il vérifie simplement si vim71 est dans le chemin, et le prépare si ce n'est pas le cas.
@echo off
echo %PATH% | find /c /i "vim71" > nul
if not errorlevel 1 goto jump
PATH = C:\Program Files\Vim\vim71\;%PATH%
:jump
cette démo est pour illustrer la logique errorlevel:
@echo on
echo %PATH% | find /c /i "Windows"
if "%errorlevel%"=="0" echo Found Windows
echo %PATH% | find /c /i "Nonesuch"
if "%errorlevel%"=="0" echo Found Nonesuch
la logique est inversée dans le code vim71 puisque errorlevel 1 est équivalent à errorlevel >= 1. Il s'ensuit que errorlevel 0 évaluerait toujours true, donc " not errorlevel 1
" est utilisé.
Postscript La vérification peut ne pas être nécessaire si vous utilisez setlocal et endlocal pour localiser vos paramètres d'environnement, par exemple
@echo off
setlocal
PATH = C:\Program Files\Vim\vim71\;%PATH%
rem your code here
endlocal
après endlocal vous êtes de retour avec votre chemin d'origine.
un commentaire au script "addPath" ; Quand on fournit un chemin avec des espaces, il vomit.
exemple: appel addPath "c:\Program fichiers (x86)\Microsoft SDKs\Windows\v7.0a \ Bin"
les rendements: 'Fichiers' n'est pas reconnu comme une commande interne ou externe, programme opérable ou fichier batch.
en général ceci est de mettre un exe/dll sur le chemin. Tant que ce fichier n'apparaîtra pas ailleurs:
@echo off
where /q <put filename here>
if %errorlevel% == 1 (
setx PATH "%PATH%;<additional path stuff>"
) else (
echo "already set path"
)
ceci est une variation de la réponse de Kevin Edwards utilisant le remplacement de chaîne. Le modèle de base est:
IF "%PATH:new_path=%" == "%PATH%" PATH=%PATH%;new_path
par exemple:
IF "%PATH:C:\Scripts=%" == "%PATH%" PATH=%PATH%;C:\Scripts
en bref, nous faisons un test conditionnel où nous tentons de supprimer/remplacer new_path
de notre variable d'environnement PATH
. Si new_path
n'existe pas la condition réussit et le new_path
sera ajouté à PATH
pour la première fois. Si new_path
déjà existe alors la condition échoue et nous n'ajouterons pas new_path
une deuxième fois.
Vous pouvez accomplir cela en utilisant PoweShell;
Test-Path $ENV:SystemRoot\YourDirectory
Test-Path C:\Windows\YourDirectory
retourne TRUE
ou FALSE
Bref, simle et facile!
comme alternative:
-
dans le dossier pour lequel vous allez rechercher la variable
PATH
, créez un fichier temporaire avec un nom si inhabituel que vous ne vous attendriez jamais à ce qu'il y ait un autre fichier sur votre ordinateur. -
utilisez la construction de script par lots standard qui vous permet d'effectuer la recherche d'un fichier en cherchant une liste de répertoires définie par une variable d'environnement (typiquement
PATH
). -
vérifiez si le résultat de la recherche correspond au chemin en question, et affichez le résultat.
-
Supprimer le fichier temporaire.
Cela pourrait ressembler à ceci:
@ECHO OFF
SET "mypath=D:\the\searched-for\path"
SET unusualname=nowthisissupposedtobesomeveryunusualfilename
ECHO.>"%mypath%\%unusualname%"
FOR %%f IN (%unusualname%) DO SET "foundpath=%%~dp$PATH:f"
ERASE "%mypath%\%unusualname%"
IF "%mypath%" == "%foundpath%" (
ECHO The dir exists in PATH
) ELSE (
ECHO The dir DOES NOT exist in PATH
)
problèmes Connus:
-
la méthode ne peut fonctionner que si le répertoire existe (ce qui n'est pas toujours le cas).
-
la création / suppression de fichiers dans un répertoire affecte son attribut" Date/heure modifiée " (qui peut parfois être un effet indésirable).
-
la création d'un nom de fichier globalement unique dans son esprit ne peut pas être considérée comme très fiable. La génération d'un tel nom n'est pas en soi une tâche insignifiante.
cette routine recherchera un chemin\ ou un fichier.ext dans la variable path
elle renvoie 0 si elle est trouvée. Le chemin\ ou le fichier peut contenir des espaces s'il est cité.
Si une variable est passée comme dernier argument, elle sera définie à d:\path\file
.
@echo off&goto :PathCheck
:PathCheck.CMD
echo.PathCheck.CMD: Checks for existence of a path or file in %%PATH%% variable
echo.Usage: PathCheck.CMD [Checkpath] or [Checkfile] [PathVar]
echo.Checkpath must have a trailing \ but checkfile must not
echo.If Checkpath contains spaces use quotes ie. "C:\Check path\"
echo.Checkfile must not include a path, just the filename.ext
echo.If Checkfile contains spaces use quotes ie. "Check File.ext"
echo.Returns 0 if found, 1 if not or -1 if checkpath does not exist at all
echo.If PathVar is not in command line it will be echoed with surrounding quotes
echo.If PathVar is passed it will be set to d:\path\checkfile with no trailing \
echo.Then %%PathVar%% will be set to the fully qualified path to Checkfile
echo.Note: %%PathVar%% variable set will not be surrounded with quotes
echo.To view the path listing line by line use: PathCheck.CMD /L
exit/b 1
:PathCheck
if "%~1"=="" goto :PathCheck.CMD
setlocal EnableDelayedExpansion
set "PathVar=%~2"
set "pth="
set "pcheck=%~1"
if "%pcheck:~-1%" equ "\" (
if not exist %pcheck% endlocal&exit/b -1
set/a pth=1
)
for %%G in ("%path:;=" "%") do (
set "Pathfd=%%~G\"
set "Pathfd=!Pathfd:\=\!"
if /i "%pcheck%" equ "/L" echo.!Pathfd!
if defined pth (
if /i "%pcheck%" equ "!Pathfd!" endlocal&exit/b 0
) else (
if exist "!Pathfd!%pcheck%" goto :CheckfileFound
)
)
endlocal&exit/b 1
:CheckfileFound
endlocal&(
if not "%PathVar%"=="" (
call set "%~2=%Pathfd%%pcheck%"
) else (echo."%Pathfd%%pcheck%")
exit/b 0
)
juste pour développer sur Heyvon's (2015.06.08) réponse en utilisant Powershell, ce simple script Powershell devrait vous donner des détails sur %path%
$env:Path -split ";" | % {"$(test-path $_);$_"}
générant ce type de sortie que vous pouvez vérifier indépendamment
True;C:\WINDOWS
True;C:\WINDOWS\system32
True;C:\WINDOWS\System32\Wbem
False;C:windows\System32\windowsPowerShell\v1.0\
False;C:\Program Files (x86)\Java\jre7\bin
pour réassembler le chemin de mise à jour:
$x=$null;foreach ($t in ($env:Path -split ";") ) {if (test-path $t) {$x+=$t+";"}};$x