Я написал набор пакетных скриптов для этого. addpath.bat добавляет элементы в путь, rmpath.bat удаляет элементы из пути, а lpath.bat просто перечисляет путь. Но тогда мне потребовалось несколько сценариев поддержки, так что есть также chkpath.bat.
Это оказалось не тривиальным и потребовало tr.exe и cat.exe, пару утилит в стиле Unix. Причина не тривиальна: никаких обратных кавычек в cmd.exe (хотя вы можете использовать для циклов для этого) и короткие имена против длинных имен.
addpath.bat:
@echo off setlocal set cwd=%~dps0 goto testit :loopy call %cwd%chkpath "%~1" if %errorlevel%==2 ( set path=%path%;%~1 ) shift :testit if not _%1==_ goto loopy call %cwd%lpath.bat endlocal & set path=%path%
ChkPath.bat:
@echo off goto START ------------------------------------------------------- chkpath.bat checks path for existence of the given segment. Returns 1 if present, 2 if not present, 0 if not checked. The matching and checking complicated by case sensitivity and "short pathnames". created sometime in 2003 and lovingly maintained since then. ------------------------------------------------------- :START setlocal enabledelayedExpansion set rc=0 set cwd=%~dps0 set curdrive=%~d0 set tr=%curdrive%\bin\tr.exe set regexe=%windir%\system32\reg.exe if _%1==_ goto Usage @REM convert arg 1 to a fully-qualified, short path name, @REM and then convert to uppercase. set toupper=%~fs1 call :ToUpper set tocheck=%toupper% if not _%TEMP%==_ goto GotTemp call :gettemp :GotTemp set d=%DATE:~4% set stamp=%d:~6%%d:~3,2%%d:~0,2%%TIME::=% set d= set tempfile1=%TEMP%\chkpath1-%stamp%.tmp echo %path% | %tr% ; \n > %tempfile1% @REM check each element in the path for the match: for /f "delims=^" %%I in (%tempfile1%) do ( if !rc!==0 ( call :CheckElt "%%I" ) ) if %rc%==0 set rc=2 goto END -------------------------------------------- * checkelt * * check one element in the path to see if it is the same * as the TOCHECK string. The element is first canonicalized. * :CheckElt @REM remove surrounding quotes set ERF=%1 if [x%ERF%]==[x] goto CheckEltDone @REM convert to fully-qualified, short paths, uppercase set TOUPPER=%~fs1% call :ToUpper if _%TOCHECK% == _%TOUPPER% set rc=1 :CheckEltDone goto:EOF -------------------------------------------- -------------------------------------------- * backtick * * invoke a command and return the result as a string. * This is like backtick in csh or bash. * To call, set variable BACKTICK to the command to be run. * The result will be stored in the env variable of the same name. * :backtick FOR /F "usebackq delims=" %%i IN (`%backtick%`) DO ( SET backtick=%%i ) goto backtick_done :backtick_none SET backtick=nothing to exec :backtick_done goto:EOF -------------------------------------------- -------------------------------------------- * gettemp * * get the temporary directory, as stored in the registry. * Relies on backtick. * * The result set TEMP. * :gettemp set regkey=HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders set regvalname=Local AppData set backtick=%regexe% query "%regkey%" /v "%regvalname%" call :backtick for /f "tokens=4" %%a in ("%backtick%") do ( set temp=%%a ) goto:EOF -------------------------------------------- -------------------------------------------- * ToUpper * * Convert a string to all uppercase. * To call, set variable TOUPPER to the thing to be converted. * The result will be stored in the env variable of the same name. * :ToUpper FOR /F "usebackq delims=" %%I IN (`echo %toupper% ^| %tr% a-z A-Z`) DO ( SET toupper=%%I ) goto:EOF -------------------------------------------- -------------------------------------------- :CleanUp if _%tempfile1%==_ goto CleanUpDone if exist %tempfile1% del %tempfile1% :CleanUpDone goto:EOF -------------------------------------------- -------------------------------------------- :Usage echo. echo Usage: chkpath ^<path^> echo checks if path element is included in path variable. echo returns 1 if yes, 2 if no, 0 if not checked. echo. goto END -------------------------------------------- :END call :CleanUp :ReallyEnd endlocal & set errorlevel=%rc% @REM set errorlevel=%rc% @REM echo %errorlevel%
lpath.bat:
@echo. @set curdrive=%~d0 @REM This form post-fixes a | at the end of each path element. Useful for debugging trailing spaces. @REM @path | %curdrive%\cygwin\bin\sed.exe -e s/PATH=// -e 's/;/^|\n/g' -e 's/$/^|/g' @REM This form shows bare path elements. @REM @path | %curdrive%\cygwin\bin\sed.exe -e 's/PATH=//' -e 's/;/^\n/g' @path | %curdrive%\utils\sed -e "s/PATH=//" | %curdrive%\utils\tr ; \n @echo.