Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
450 views
in Technique[技术] by (71.8m points)

path - How to keep the value of a variable outside a Windows batch script which uses "delayed expansion local" mode?

Context: I need to call a Windows batch script which would update my PATH by adding another path 'xxx' at the end of it, but:

  • without any duplicate
    (if I add 'xxx' to a PATH like 'aaa;xxx;bbb', I need an updated PATH like 'aaa;bbb;xxx')
  • without any aggregation
    (I can call the script repeatedly without ending up with 'aaa;bbb;xxx;xxx;xxx;...')

What I have tried:

The following function takes care of any duplicate and does the job

:cleanAddPath -- remove %~1 from PATH, add it at the end of PATH
SETLOCAL ENABLEDELAYEDEXPANSION
set PATH=!PATH:%~2=!
set PATH=!PATH:;;=;!
set PATH=%PATH%;%~2
set P=!P:;;=;!
echo %PATH%
echo -------------
ENDLOCAL  
exit /b

But, it needs delayed expansion local mode, which means: at the end of the script (or here, at the end of the function cleanAddPath), whatever has been set for %PATH% is thrown away.

I could ask the users (for which I write the script) to launch their cmd with a cmd /V:ON option (activating the delayed expansion, otherwise off by default), but that is not practical.

How can I modify the PATH variable the way I described above, and still have it updated in my current DOS session after calling said script?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The page "DOS - Function Collection" gives great example on how a function can return a value in DOS, even when using delayed expansion mode:

The following function will update any variable you want with an addition PATH:

:cleanAddPath -- remove %~2 from %~1, add it at the end of %~1
SETLOCAL ENABLEDELAYEDEXPANSION
set P=!%~1!
set P=!P:%~2=!
set P=!P:;;=;!
set P=!P!;%~2
set P=!P:;;=;!
(ENDLOCAL & REM.-- RETURN VALUES
  SET "%~1=%P%"
)
exit /b

Note the concatenation of paths using. As jeb comments:

The line set P=%P%;%~2 is critical if your path contains ampersands like in C:Documents&Settings.
Better change to set "P=!P!;%~2".

The SET "%~1=%P%" is the part which allows to memorize (in the variable represented by %~1) the value you have set using delayed expansion features.
I initially used SET "%~1=%P%" !, but jeb comments:

The command SET "%~1=%P%" ! could be simplified to SET "%~1=%P%" as the trailing exclamation mark has only a (good) effect in delayed expansion mode and if you prepared %P% before.

To update your PATH variable, you would call your function with:

call :cleanAddPath PATH "C:mypathoadd"

And it will persists after leaving that script, for your current DOS session.

dbenham's answer points to a more robust answer (upvoted), but in my case this script is enough.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...