## PATH issues

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
dbenham
Expert
Posts: 2383
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

### PATH issues

Fairly frequently I want to examine the PATH contents, and it is really a pain to visually parse when it contains many paths. I grew tired of copying the value to a text editor and adding new lines manually. I figured there must be a way to programmatically split the path into multiple lines appropriately.

I came up with the following (to be executed on the command line)

Code: Select all

for %P in ("%path:;=" "%") do @echo(%~P

It worked great, and I was curious if anyone had posted it before.

Of course jeb has already posted a nearly identical solution at 'Pretty print' windows %PATH% variable - how to split on ';' in CMD shell

jeb goes on to show how the solution fails if the PATH contains quoted ; within it. The problem is ; is a valid character for folder names, and must be quoted in the PATH. He posted a safe solution for any situation on the same thread. I won't post his safe solution here (nor some minor improvements I suggested). Just follow the link.

I then started thinking about PATH, and how it is common practice to append to PATH using something like:

Code: Select all

set PATH=%PATH%;c:\new_path\

Even Microsoft recommends the operation:

Code: Select all

C:\>help pathDisplays or sets a search path for executable files.PATH [[drive:]path[;...][;%PATH%]PATH ;Type PATH ; to clear all search-path settings and direct cmd.exe to searchonly in the current directory.Type PATH without parameters to display the current path.Including %PATH% in the new path setting causes the old path to beappended to the new setting.

But this will fail if the PATH contains any of the following valid unquoted path characters: ^ &

This fix is not reliable:

Code: Select all

set "path=%path%;\new_path"
because the PATH may already contain quotes. In fact, the PATH must contain quotes if any path includes the ; character.

Here is a valid PATH that wont extend properly either with or without enclosing quotes:

Code: Select all

PATH=c:\This & That;"c:\A path with ; semicolon";c:\a third path

The solution is fairly simple - make sure the PATH is expanded using delayed expansion.

Here is a simple function that will reliably append any path to the existing PATH as long as it is not called while delayed expansion is enabled. (thanks Ed for pointing out this limitation in your post below).

Code: Select all

@echo off:PathAdd pathVar:: pathVar is the name of a variable containing the new path to append to PATHsetlocal enableDelayedExpansionfor /f "tokens=* delims=;" %%N in ("!%~1!") do (  for /f "tokens=* delims=;" %%P in ("!PATH!") do (    endlocal    set path=%%P;%%N  ))exit /b

Dave Benham
Last edited by dbenham on 12 Nov 2011 10:47, edited 1 time in total.

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

### Re: PATH issues

'
I just don't understand why it apparently is so important for some (dBenham) to always stay in disable delayed.
I default to delayed, and when I need it, I can always switch to disabled.
The only reason I can think of would be if you are working from the terminal where setlocal doesn't apply.

What is so GOOD about disable delayed, because all I am having with it are problems having to escape special chars.
You can't even do the simplest thing in disable delayed:

Code: Select all

set "$var=%$var%"
The contents may have changed !, did you use escapes ? o well, that's too bad.

dbenham
Expert
Posts: 2383
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

### Re: PATH issues

I want to do my part to let Ed relax and sleep well at night
So here is a version that can be called with delayed expansion enabled or disabled

Code: Select all

@echo off:PathAdd pathVar:: pathVar is the name of a variable containing the new path to append to PATHsetlocalset "NotDelayed=!"setlocal enableDelayedExpansionset "rtn=!path!;!%~1!"set "rtn=!rtn:%%=%%~A!"set "rtn=!rtn:"=%%~B!"if not defined NotDelayed set "rtn=!rtn:^=^^^^!"if not defined NotDelayed set "rtn=%rtn:!=^^^!%" !set "replace=%% """"for /f "tokens=1,2" %%A in ("!replace!") do (  endlocal & endlocal  set "path=%rtn%" !)exit /b

We don't need <CR> or <LF> support so I used a simplified version of jeb's safe return technique.

Dave Benham

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

### Re: PATH issues

'
You are too nice for me, I wasn't going to use the path anyways, never, I already hate the fact that ATI is in there, who the hell they think they are.

No, I just made a habbit of it to always address external sources by absolute sourcename.

dbenham
Expert
Posts: 2383
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

### Re: PATH issues

Another common PATH question is "How do I determine if mypath already exists within PATH? - If it doesn't, append it"

It is surprisingly difficult to get a safe, reliable solution that works in all situations.

I've documented many issues that plague this problem, as well as the best solution I could come up with, at StackOverflow: How to check if directory exists in %PATH%?

It's a good read if you have any DOS geek in you. It even has the jeb stamp of approval

Dave Benham

foxidrive
Expert
Posts: 6033
Joined: 10 Feb 2012 02:20

### Re: PATH issues

dbenham wrote:Another common PATH question is "How do I determine if mypath already exists within PATH? - If it doesn't, append it"

It is surprisingly difficult to get a safe, reliable solution that works in all situations.

There are lots of gotchas in the path as outlined there. An interesting read, though I didn't read it fully.

However, how about using this to test if a directory is on the path:

Code: Select all

@echo offset "folder=c:\to the\path to test"md "%folder%" 2>nulecho @echo abc>"%folder%\dang fool, don't run me.bat"pushd "c:\"set "var="for /f "delims=" %%a in ('"dang fool, don't run me.bat" 2^>nul') do set "var=%%a"if defined var (echo Yes, the "%folder%" is on the path.) else (echo Nope, "%folder%" ain't on the path")del "%folder%\dang fool, don't run me.bat" 2>nulpopdpause

It won't work if the folder is on an optical/read-only media but I think it should handle any other case.