15

For one CMD session I can easily set a new path: SET PATH=%PATH%;"insert custom path here"

Doing so in a batch file does not consider whether the custom path is already included. How do I avoid duplicating it (i.e. check whether it is already contained in the PATH "string").

Remarks:

  1. Related: How do I append user-defined environment variables to the system variable PATH in Windows 7?
  2. Related: How can I permanently append an entry into the system's PATH variable, via command line?
  3. Same question for UNIX: Add directory to $PATH if it's not already there
  4. Some "CMD" String ops explained: http://ss64.com/nt/syntax-replace.html
Horst Walter
  • 1,899
  • 7
  • 27
  • 46
  • It should be pointed out that in this context, the duplication is harmless. It would probably be more sensible to allow the duplication to occur than to try to avoid it and introduce the risk of a false positive. – Harry Johnston Sep 27 '12 at 22:58

4 Answers4

20

Similar to MaddHackers answer, just more compact.
echo %path%|find /i "%np%">nul || set path=%path%;%np%

%np% is your new path, of course you can use literals instead. What it does: echo %path%|find /i "%np%">nul searches existing path for a string, discarding output. || means execute on failure, so it means: Search path for string to be added, and if not found, add it.

Edit: Generally it's not required to quote paths, even those containig spaces, but if you do want to quote them, this version will work with double quoted paths:
echo %path%|find /i "%np:"=%">nul || set path=%path%;%np%

Edit: changed findstr /i /c: to find /i as findstr may misinterpret some sequences as noted by KubaOber in comments

wmz
  • 7,102
  • 1
  • 21
  • 32
  • Nice, I knew there was a cleaner way to do that... still prefer bash, but that's just me :D Thanks for the help! – MaddHacker Sep 27 '12 at 15:45
  • Nice, but does it work with spaces in the path? I have tested it with my particular paths, the one "quoted and with spaces" gets re-added. One just quoted but no spaces seems to work. – Horst Walter Sep 27 '12 at 16:06
  • 1
    @HorstWalter Yes it should work with any path (I've just checked with some including spaces). What do you mean by "quoted"? You do not need to use quotes in paths, even those containing spaces. If your `%np%` contain quotes - yes, it will cause it to misbehave. – wmz Sep 27 '12 at 16:36
  • I have used "", e.g. "my path". OK, I'll try without quotes, and should have written "in quotes", sorry it was misleading. – Horst Walter Sep 27 '12 at 16:57
  • 2
    @HorstWalter See my edit. This is only an issue if you use variable, using literals (as in `echo %path%|findstr /i /c:"my path">nul || set path=%path%;"my path"`) should work fine. – wmz Sep 27 '12 at 17:15
  • Excellent, thanks to you and also MaddHacker, very nice! I appreciate your efforts. – Horst Walter Sep 27 '12 at 20:23
  • **findstr** is the wrong utility to use. It will gladly interpret some of the backsplashes as escapes. **find** works great, though. – Kuba hasn't forgotten Monica Sep 04 '15 at 18:05
  • @KubaOber please give an example of incorrect behaviour **when used with `/c` option** forcing literal match – wmz Sep 04 '15 at 19:29
  • 1
    @wmz `echo d\. | findstr /c:"d\."` fails, but `echo d\. | find "d\."` succeeds – Kuba hasn't forgotten Monica Sep 04 '15 at 19:53
  • @KubaOber You're right, another 'feature' of cmd tools :-( Although I tried various combinations and I think those [incorrectly interpreted] sequences will not actually happen in real paths... but just to be safe I will change it to `find`. Thanks for picking this up! – wmz Sep 04 '15 at 21:57
  • @wmz I only found about it because I ran into a path that triggered it :( It was a relative path with dots, like `foo\..\bar` – Kuba hasn't forgotten Monica Sep 04 '15 at 22:02
  • Update request: If path has parentheses in it (e.g. "C:\Program Files (x86)\Common Files...") then `echo %path%...` didn't work for me, but surrounding the path in quotes (i.e. `echo "%path%"...`) does. – JSmart523 Sep 15 '21 at 19:02
5

I know it's dirty, but this should work:

 SET PATH=$(echo $PATH | awk -F"%checkstr%" '{ print ($(NF-1) ~ 0) ? $PATH:%newpath% : $PATH; }')

where %checkstr% is the string to check for in the PATH and %newpath% is the new PATH to append to the current PATH

Hope that helps, and I'm sure there's an easier way, but that should do the trick for now.

EDIT

So if you don't want to add the UNIX tools to Windows, you can try this batch syntax:

echo %PATH% | find /C /I "<string to find>" > out.txt 
set /p dne= < out.txt
if 0 EQU %dne% (set PATH=%PATH%;"<custom path>")
del out.txt

Ugh, not any prettier, and can be done as one line if you can get the pipe'ed find command to work as a subcommand in the if statement...

MaddHacker
  • 381
  • 2
  • 8
2

Script based around the answer by "wmz" :

@ECHO off
ECHO java_home=%JAVA_HOME%
SET javapath=%JAVA_HOME%\bin
ECHO %path%|findstr /i /c:"%javapath:"=%">nul || set path=%path%;%javapath%
ECHO Path=%path%
PAUSE
djangofan
  • 2,851
  • 9
  • 34
  • 35
1

Updated answer for 2021:

set is no longer working and we need to use setx (little different syntax):

SET mypath=C:\dev\vendor\sass\1.32.4
ECHO %Path%|findstr /i /c:"%mypath:"=%">nul || setx Path "%Path%";%mypath%