1

Some people say that their path is too long, However, the problem is often caused by recurring call of the same batch script with code like set mypath=%mypath%;appendix. People just do not realize that. I proposed a solution to restore the env variables upon exit

set old_path=classpath
set classpath=%classpath%;appendix
java myApp
set classpath=old_path

But it is tedious and error prone. I may easily forget to recover or fail due to exception, another exit path. Can this be done automatically?

We can start with a smart appendix. I mean that the problem is caused by appending the path unconditionally. You already have the appendix on your path but add it over and over again. That is the root of the problem. I think that the same problem applies to bash. Might be I can check the path and add only those entries which are missing? What is the standard solution?

Community
  • 1
  • 1
Val
  • 1
  • 8
  • 40
  • 64
  • Please don't tag this `bash`. [tag:bash] is different from [tag:batch-file]. – devnull Oct 28 '13 at 09:00
  • Do not remove the bash. Bash is different from batch-file. – Val Oct 28 '13 at 09:02
  • 1
    Consider using the `java -classpath` option. E.g. `java -classpath "$CLASSPATH;appendix" myApp` or similar. – svante Oct 28 '13 at 09:22
  • I do not understand why `bash` instead of `batch-file` tag is deleted? What is the purpose of deleting the bash tag? Is it to show that I am wrong guessing that the problem does not exist in Linux? Editing the question is a strange way to answer it. – Val Oct 28 '13 at 09:25
  • Your question seems to be about windows batch-files, I can't see why this should be relevant for bash – jeb Oct 28 '13 at 10:09
  • You should read [How to check if directory exists in %PATH%?](http://stackoverflow.com/a/8046515/463115), with that solution you can add a path only when it's not exists – jeb Oct 28 '13 at 10:13
  • @jeb Just saying "I do not see why" you say that you is from another planet, where bash is not the default Linux shell but something different and do not bother to read the tag descriptions. – Val Oct 28 '13 at 11:01

4 Answers4

4

first, your code can't work, e.g. old_path is a string in your last command.

set "old_path=%classpath%"
set "classpath=%classpath%;%appendix%"
java myApp
set "classpath=%old_path%"

second, just use a new environment in the batch to avoid such issues:

@echo off
echo %path%
setlocal
set "path="
echo %path%
endlocal
echo %path%
Endoro
  • 37,015
  • 8
  • 50
  • 63
2

EDITED - To adjust to corrections in comments (and no jeb, no bulletproof, just try not to shoot your foot)

Just for completion, this batch adds one or more elements to indicated variable only if not already included

@echo off

    call :addToVariable %*

    exit /b

:addToVariable
    rem %1 = variable name where to add elements
    rem %2 = element to add
    rem %3-... the rest of the elements. Will be shifted to retrieve

    rem if no data, no work
    if "%~1"=="" goto :EOF
    if "%~2"=="" goto :EOF

    rem prepare environment to work
    setlocal enableextensions enabledelayedexpansion

    rem get variable name to work
    set "_var=%~1"

    rem get original value of variable 
    if defined %_var% (
        set "_value=!%_var%:"=!"
        rem " this line does nothing but correct sintax highlighting
    ) else (
        set _value=
    )

    rem skip to arguments with elements to include
    shift

    rem list of elements to add to original variable
    set _add=

:addToVariableLoop
    rem iterate over parameters
    for %%d in ( %1 ) do (

        rem test if new directory already in original or temporary variable
        echo ";!_value!;!_add!;" | findstr /i /c:";%%~d;" >nul 2>nul 

        rem if not in variable, add to temporary variable
        if not errorlevel 1 (
            echo [%%~d] already included
        ) else (
            echo adding [%%~d] 
            set "_add=!_add!;%%~d"
        )

    )

    rem check if more elements are pending in call
    if not "%~2"=="" (
        shift
        goto :addToVariableLoop
    )

    set "_value=%_value%%_add%"

    endlocal & set "%_var%=%_value%"
    goto :EOF

If batch file is pathAdd.cmd, to add to path variable call as

pathAdd path c:\windows;c:\test;"c:\something more"

To add to classPath variable call as

pathAdd classPath c:\windows\system32\drivers

To add to PSModulePath variable call as

pathAdd PSModulePath "c:\Somewhere over the rainbow";c:\Users

....

MC ND
  • 69,615
  • 8
  • 84
  • 126
  • 1
    +1, Even this is far away from bullet proof. Try it with `path="C:\documents & settings";C:\windows\system32` – jeb Oct 28 '13 at 10:38
  • Ok.I still working on my solution ,but now I'm awaiting for jeb's bulletproof answer with more impatience :-D . – npocmaka Oct 28 '13 at 10:43
  • @MC ND - two things.The OP needs an solution for claspath - it contains files (`.jar` files in particular), but I think your script will work in this case too.And you can dequote the tokens in for loop just with `%%~d` – npocmaka Oct 28 '13 at 10:53
  • You are right jeb, no bulletproof. npocmaka, i must be blind, thank you. Anyway, updated to a more "correct" answer – MC ND Oct 28 '13 at 13:23
1

Here's a script that rebuilds a %path% variable to contain only short paths (8.3 notation):

@echo off
setlocal disableDelayedExpansion
REM Creating a Newline variable (the two blank lines are required!)
set NLM=^


set NL=^^^%NLM%%NLM%^%NLM%%NLM%

setlocal enableDelayedExpansion
set _path_=!path:;=%NL%!
rem  iteration
set "short_path="
for /f "delims=" %%I in ("!_path_!") do set  short_path=!short_path!;%%~dpsnxI
endlocal & set short_path=%short_path%
echo %short_path%

endlocal

You can replace PATH with classpath to get short paths of it's elements.Eventually could help.

You can also check length of the appendix and the path to see if you'll reach the limit. I'll update the answer with a script that will include only missing elements....

npocmaka
  • 55,367
  • 18
  • 148
  • 187
  • 1
    +1, But fails when a path contains itself a semicolon (it's allowed) – jeb Oct 28 '13 at 10:14
  • Wow..It's really allowed and even can be put in `%PATH%` variable if it's enclosed with quotes.I must re-wrote this to fix it. – npocmaka Oct 28 '13 at 10:22
  • 1
    It's solved at [Pretty print windows PATH](http://stackoverflow.com/a/5472168/463115) – jeb Oct 28 '13 at 10:34
1

If the purpose of this question is to know if the path to a certain given file exists in %PATH% and if not, insert it (and this is the only reason to do that, I think), then it may solved in a slightly different way: "How to check if the directory of a certain file exist in %PATH%" already? This question may be easily solved this way:

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

If you don't know the extension of the search file, just review all of them:

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

This method works with any filenames or extensions, or any other variable besides PATH (like classpath).

Aacini
  • 65,180
  • 12
  • 72
  • 108