it-swarm.com.de

Wie prüfe ich, ob das Verzeichnis in% PATH% existiert?

Wie kann geprüft werden, ob in der Umgebungsvariable PATH bereits ein Verzeichnis vorhanden ist? Hier ist ein Anfang. Alles, was ich mit dem folgenden Code erreicht habe, ist das erste Verzeichnis in% PATH%. Da dies eine FOR-Schleife ist, würden Sie denken, dass sie alle Verzeichnisse in% PATH% auflisten würde, aber nur das erste Verzeichnis erhält. 

Gibt es einen besseren Weg, dies zu tun? So etwas wie find oder findstr für die Variable% PATH%? Ich möchte nur prüfen, ob ein Verzeichnis in der Liste der Verzeichnisse in% PATH% vorhanden ist, um das Hinzufügen eines möglicherweise bereits vorhandenen Verzeichnisses zu vermeiden.

FOR /F "delims=;" %%P IN ("%PATH%") DO (
    @ECHO %%~P
)
58
Axl

Ich habe seit einiger Zeit keine Batch-Datei programmiert, aber:

echo ;%PATH%; | find /C /I ";<string>;"

sie sollten 0 angeben, wenn string nicht gefunden wird, und 1 oder mehr, falls dies der Fall ist.

BEARBEITEN: Dank Panos wurde die Groß- und Kleinschreibung nicht beachtet.

36
Randy

Eine andere Möglichkeit, um zu überprüfen, ob sich etwas im Pfad befindet, besteht darin, eine unschuldige ausführbare Datei auszuführen, die dort nicht fehlschlägt, und das Ergebnis zu überprüfen. Als nächstes prüft das nächste Code-Snippet, ob maven im Pfad enthalten ist:

mvn --help > NUL 2> NUL 
if errorlevel 1 goto mvnNotInPath

Also versuche ich mvn --help auszuführen, die Ausgabe zu ignorieren (ich möchte eigentlich nicht die Hilfe sehen, wenn maven vorhanden ist) (> NUL), und auch die Fehlermeldung nicht, wenn maven nicht war gefunden (2> NUL).

21
bert bruynooghe

Nachdem ich die Antworten hier gelesen habe, denke ich, dass ich einen neuen Standpunkt einbringen kann: Wenn der Zweck dieser Frage ist zu wissen, wenn der Pfad zu einer bestimmten ausführbaren Datei in %PATH% vorhanden ist, und wenn nicht, fügen Sie ihn ein (und Dies ist der einzige Grund , um das zu tun, denke ich), dann kann es auf eine etwas andere Art gelöst werden: "Wie prüfe ich, ob das Verzeichnis eines bestimmten ausführbaren Programms in% PATH% vorhanden ist?" Diese Frage kann auf diese Weise leicht gelöst werden:

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"
)

Wenn Sie die Erweiterung der ausführbaren Datei nicht kennen, überprüfen Sie einfach alle:

set "progpath="
for %%e in (%PATHEXT%) do (
   if not defined progpath (
      for %%p in (programname.%%e) do set "progpath=%%~$PATH:p"
   )
)
7
Aacini

Mit for und delims können Sie nicht eine beliebige Anzahl von Feldern erfassen (wie Adam wies auch aus), so dass Sie stattdessen eine Schleifentechnik verwenden müssen. Das folgende Befehlsskript listet jeden Pfad in der Umgebungsvariablen PATH in einer separaten Zeile auf:

@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

Es simuliert ein klassisches whilewend -Konstrukt, das in vielen Programmiersprachen zu finden ist .. Mit dieser Funktion können Sie etwas wie findstr verwenden, um anschließend einen bestimmten Pfad zu filtern und nach diesem zu suchen. Wenn Sie beispielsweise das obige Skript in einer Datei mit dem Namen tidypath.cmd gespeichert haben, können Sie Folgendes an findstr weiterleiten und nach Pfaden im Standardprogrammverzeichnis suchen (mit einer Übereinstimmung, bei der die Groß- und Kleinschreibung nicht beachtet wird):

> tidypath | findstr /i "%ProgramFiles%"
6
Atif Aziz

Dies wird nach einem exakten, aber von der Groß- und Kleinschreibung nicht abhängigen Treffer suchen.

for %P in ("%path:;=";"%") do @if /i %P=="PATH_TO_CHECK" echo %P exists in PATH

oder in einer Batchdatei (z. B. checkpath.bat), die ein Argument enthält:

@for %%P in ("%path:;=";"%") do @if /i %%P=="%~1" echo %%P exists in PATH

In der letzteren Form könnte man z.B. checkpath "%ProgramFiles%", um festzustellen, ob der angegebene Pfad bereits in PATH vorhanden ist.

Bitte beachten Sie, dass diese Implementierung davon ausgeht, dass in einem einzelnen Pfadelement keine Semikola oder Anführungszeichen stehen.

4
mousio

Ich nahm Ihre Implementierung mit der for - Schleife und erweiterte sie so, dass sie alle Elemente des Pfads durchläuft. Bei jeder Wiederholung der for-Schleife wird das erste Element des Pfads (% p) aus dem gesamten Pfad entfernt (in% q und% r gespeichert).

@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

Beispielausgabe:

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
2
indiv

Wenn Ihre Frage "Warum funktioniert dieses Cmd-Skriptfragment nicht?" dann lautet die Antwort, dass for /f über Zeilen iteriert. Die Variable delims teilt Zeilen in Felder auf, aber Sie erfassen nur das erste Feld in %%P. Es ist nicht möglich, eine beliebige Anzahl von Feldern mit einer for /f-Schleife zu erfassen.

2
Adam Mitz

Sie können die Ersetzung der Teilzeichenfolge auch verwenden, um das Vorhandensein einer Teilzeichenfolge zu testen. Hier entferne ich Anführungszeichen, um PATH_NQ zu erstellen, dann entferne ich "c:\mydir" aus dem PATH_NQ und vergleiche es mit dem Original, um zu sehen, ob sich etwas geändert hat:

set PATH_NQ=%PATH:"=%
if not "%PATH_NQ%"=="%PATH_NQ:c:\mydir=%" goto already_in_path
set PATH=%PATH%;c:\mydir
:already_in_path
2
Kevin Edwards

Verzeichnis zu PATH hinzufügen, falls noch nicht vorhanden:

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%)
2
Noam Manos

Ich habe einige der obigen Antworten kombiniert, um sicherzustellen, dass ein gegebener Pfadeintrag genau wie angegeben mit so viel Kürze wie möglich und ohne Junk-Echos in der Befehlszeile vorhanden ist.

set myPath=<pathToEnsure | %1>
echo ;%PATH%; | find /C /I ";%myPath%;" >nul
if %ERRORLEVEL% NEQ 0 set PATH=%PATH%;%myPath%
2
Redsplinter

Sie können dies mit PoweShell erreichen.

Test-Path $ENV:SystemRoot\YourDirectory
Test-Path C:\Windows\YourDirectory

Dies gibt TRUE oder FALSE zurück.

Kurz, einfach und leicht!

1
Heyvoon

Aufbauend auf der Antwort von rcar müssen Sie sicherstellen, dass ein Teilstring des Ziels nicht gefunden wird.

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
1
Adam Mitz

Nur als Alternative:

  1. Erstellen Sie in dem Ordner, in dem Sie die Variable PATH suchen, eine temporäre Datei mit einem so ungewöhnlichen Namen, dass Sie niemals eine andere Datei auf Ihrem Computer erwarten würden.

  2. Verwenden Sie das Standard-Batch-Skriptkonstrukt, mit dem Sie die Suche nach einer Datei durchführen können, indem Sie eine Verzeichnisliste nachschlagen, die von einer Umgebungsvariablen (normalerweise PATH) definiert wird.

  3. Prüfen Sie, ob das Ergebnis der Suche mit dem betreffenden Pfad übereinstimmt, und zeigen Sie das Ergebnis an.

  4. Löschen Sie die temporäre Datei.

Das könnte so aussehen:

@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
)

Bekannte Probleme:

  1. Die Methode kann nur funktionieren, wenn das Verzeichnis existiert (was nicht immer der Fall ist).

  2. Das Erstellen/Löschen von Dateien in einem Verzeichnis wirkt sich auf das Attribut 'Änderungsdatum/-zeit' aus (was manchmal unerwünscht ist).

  3. Das Erstellen eines weltweit eindeutigen Dateinamens kann nicht als sehr zuverlässig angesehen werden. Die Generierung eines solchen Namens ist an sich keine triviale Aufgabe.

1
Andriy M

Diese Version funktioniert ziemlich gut. Es prüft einfach, ob vim71 im Pfad ist, und setzt es voran, wenn nicht.

@echo off
echo %PATH% | find /c /i "vim71" > nul
if not errorlevel 1 goto jump
PATH = C:\Program Files\Vim\vim71\;%PATH%
:jump

Diese Demo soll die Fehlerlevel-Logik veranschaulichen:

@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

Die Logik ist im vim71-Code umgekehrt, da errorlevel 1 dem errorlevel> = 1 entspricht. Daraus folgt, dass der errorlevel 0 immer true auswertet, sodass "not errorlevel 1" verwendet wird.

Postscript Die Überprüfung ist möglicherweise nicht erforderlich, wenn Sie setlocal und endlocal verwenden, um Ihre Umgebungseinstellungen zu lokalisieren, z.

@echo off
setlocal
PATH = C:\Program Files\Vim\vim71\;%PATH%
rem your code here
endlocal

Nach dem Endlokal sind Sie wieder mit Ihrem ursprünglichen Pfad.

1
Chris Degnen

Dies ist eine Variation der Antwort von Kevin Edwards mit dem Ersetzen der Zeichenkette ..__ Das grundlegende Muster ist:

IF "%PATH:new_path=%" == "%PATH%" PATH=%PATH%;new_path

Zum Beispiel:

IF "%PATH:C:\Scripts=%" == "%PATH%" PATH=%PATH%;C:\Scripts

Kurz gesagt: Wir machen einen bedingten Test, bei dem wir versuchen, new_path aus unserer Umgebungsvariablen PATH zu entfernen/zu ersetzen. Wenn new_path nicht vorhanden ist, ist die Bedingung erfolgreich und der new_path wird zum ersten Mal an PATH angehängt. Wenn new_path bereits vorhanden ist, schlägt die Bedingung fehl und wir werden new_path kein zweites Mal hinzufügen.

1
Stephen Quan

Ein Kommentar zum Skript "addPath"; Wenn Sie einen Pfad mit Leerzeichen angeben, wird er ausgelöst.

Beispiel: Call addPath "c:\Programme (x86)\Microsoft SDKs\Windows\v7.0A\Bin"

ausbeuten: 'Dateien' wird nicht als interner oder externer Befehl, bedienbares Programm oder Stapelverarbeitungsdatei erkannt.

1
Morten Grøtan

Sie erwähnen, dass Sie vermeiden möchten, das Verzeichnis dem Suchpfad hinzuzufügen, wenn es dort bereits vorhanden ist. Ist es Ihre Absicht, das Verzeichnis dauerhaft im Pfad zu speichern, oder nur temporär für die Batchdatei?

Wenn Sie Verzeichnisse dauerhaft zu PATH hinzufügen (oder entfernen) möchten, werfen Sie einen Blick auf das Dienstprogramm Path Manager (pathman.exe) in Windows Resource Kit Tools für Verwaltungsaufgaben, http://support.Microsoft.com/kb/927229 . Damit können Sie Komponenten von System- und Benutzerpfaden hinzufügen oder entfernen und Unregelmäßigkeiten wie doppelte Einträge behandeln.

Wenn Sie den Pfad für eine Batchdatei nur vorübergehend ändern müssen, würde ich nur den zusätzlichen Pfad vor dem Pfad hinzufügen, wobei die Gefahr eines geringfügigen Leistungseinbruchs aufgrund eines doppelten Eintrags im Pfad besteht.

1
ketorin

Im Allgemeinen ist dies eine exe/dll auf dem Pfad. Solange diese Datei nirgendwo anders angezeigt wird:

@echo off
where /q <put filename here>    
if %errorlevel% == 1 (
    setx PATH "%PATH%;<additional path stuff>"
) else (
    echo "already set path"
)
1
user1454091

Diese Routine sucht nach einem Pfad\oder nach einer Datei.ext in der Pfadvariablenit gibt 0 zurück, wenn sie gefunden wird. Der Pfad\oder die Datei kann Leerzeichen enthalten, wenn ... .. Wenn eine Variable als letztes Argument übergeben wird, wird sie auf d:\path\file gesetzt.

@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
)
0
carlsomo

Um nur auf Heyvoon (2015.06.08) response mit Powershell einzugehen, sollte dieses einfache Powershell-Skript Details zu% path% enthalten.

$env:Path -split ";" | % {"$(test-path $_);$_"}

erzeugen dieser Art von Ausgabe, die Sie unabhängig überprüfen können

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

zum Aktualisieren neu zusammenstellen Pfad:

$x=$null;foreach ($t in ($env:Path -split ";") ) {if (test-path $t) {$x+=$t+";"}};$x
0
Albert

-contains hat für mich gearbeitet

$pathToCheck = "c:\some path\to\a\file.txt"

$env:Path - split ';' -contains $pathToCheck

Um den Pfad hinzuzufügen, wenn er noch nicht existiert, benutze ich

$pathToCheck = "c:\some path\to\a\file.txt"

if(!($env:Path -split ';' -contains $vboxPath)) {
  $documentsDir = [Environment]::GetFolderPath("MyDocuments")
  $profileFilePath = Join-Path $documentsDir "WindowsPowerShell/profile.ps1"
  Out-File -FilePath $profileFilePath -Append -Force -Encoding ascii -InputObject "`$env:Path += `";$pathToCheck`""
  Invoke-Expression -command $profileFilePath
}
0