program tip

Windows에서 PATH 환경 변수를 과도하게 채우는 것을 어떻게 피합니까?

radiobox 2020. 7. 25. 10:46
반응형

Windows에서 PATH 환경 변수를 과도하게 채우는 것을 어떻게 피합니까?


시스템에서 실행 파일을 관리하는 데 사용하는 방법이 무엇인지 알고 싶습니다. 예를 들어 명령 줄을 통해 거의 모든 것을 액세스 할 수 있지만 이제는 경로 문자열의 한계에 도달하므로 더 이상 dir을 추가 할 수 없습니다.

그래서 당신은 무엇을 추천합니까? 오래 전에, 경로에 속한 Dir에서 실행 파일의 softLinks를 사용하려고 시도했지만 그 방법은 작동하지 않았습니다. 알려진 Dir에 "실행 가능"만 던지십시오. 거의 모든 응용 프로그램에 파일 세트가 필요하다는 문제가 있기 때문에 이것은 나쁩니다. 실행 파일과 그의 모든 파일을 알려진 Dir에 던지면 이것이 작동하지만 파일 이름이 충돌 할 가능성은 매우 높습니다. 하드 링크를 만드시겠습니까? 모르겠어요 어떻게 생각해?


내가 생각할 수있는 한 가지 방법은 다른 환경 변수를 사용하여 부분 경로를 저장하는 것입니다. 예를 들어

C:\this_is_a\long_path\that_appears\in_multiple_places\subdir1;
C:\this_is_a\long_path\that_appears\in_multiple_places\subdir2;

그런 다음과 같은 새로운 환경 변수를 만들 수 있습니다

SET P1=C:\this_is_a\long_path\that_appears\in_multiple_places

그 후 당신의 원래 경로는

%P1%\subdir1;
%P1%\subdir2;

편집 : 다른 옵션은 적절한 파일 을 가리키는 파일을 bin보유 하는 디렉토리 를 만드는 것 입니다..bat.exe

편집 2 : Ben Voigt의 다른 답변에 따르면 다른 환경 변수를 제안한대로 %PATH%저장하면 확장되기 때문에 길이가 줄어들지 않을 수 있다고 언급합니다 . 이것은 사실 일 수 있으며 테스트하지 않았습니다. 그러나 다른 옵션은 더 긴 디렉토리 이름에 8dot3 양식을 사용 C:\Program Files하는 것 C:\PROGRA~1입니다. 예를 들어 일반적으로와 동일합니다 . dir /x더 짧은 이름을 볼 수 있습니다 .

편집 3 : 이 간단한 테스트로 벤 보이 그가 옳다고 믿습니다.

set test1=hello
set test2=%test1%hello
set test1=bye
echo %test2%

이것의 끝에, hellohello보다 출력 이 나타납니다 byehello.

편집 4 : 배치 파일을 사용하여에서 특정 경로를 제거하기로 결정한 경우 %PATH%프로세스가 투명하도록 배치 파일에서 실행 파일로 인수를 전달하는 방법에 대해 우려 할 수 있습니다 (예 : 차이가 있음을 알지 못함) 배치 파일 호출과 실행 파일 호출 사이). 배치 파일을 작성하는 데 많은 경험이 없지만 이것은 잘 작동하는 것 같습니다.

@echo off

rem This batch file points to an executable of the same name
rem that is located in another directory. Specify the directory
rem here:

set actualdir=c:\this_is\an_example_path

rem You do not need to change anything that follows.

set actualfile=%0
set args=%1
:beginloop
if "%1" == "" goto endloop
shift
set args=%args% %1
goto beginloop
:endloop
%actualdir%\%actualfile% %args%

일반적으로 하드 드라이브 포맷과 같은 배치 파일로 모든 종류의 작업을 수행 할 수 있으므로 인터넷에서 배치 파일을 실행하는 데주의해야합니다. 위의 코드 (내가 쓴)를 신뢰할 수 없다면 줄을 바꾸어 테스트 할 수 있습니다

%actualdir%\%actualfile% %args%

echo %actualdir%\%actualfile% %args%

이상적으로는 모든 라인을 실행하기 전에 정확히 무엇을해야하는지 알아야합니다.


그러면 % PATH % 환경 변수를 구문 분석하고 각 디렉토리를 해당하는 짧은 이름으로 변환 한 다음 다시 정리하십시오.

@echo off

SET MyPath=%PATH%
echo %MyPath%
echo --

setlocal EnableDelayedExpansion

SET TempPath="%MyPath:;=";"%"
SET var=
FOR %%a IN (%TempPath%) DO (
    IF exist %%~sa (
        SET "var=!var!;%%~sa"
    ) ELSE (
        echo %%a does not exist
    )
)

echo --
echo !var:~1!

출력을 가져 와서 환경 변수에서 PATH 변수를 업데이트하십시오.


Windows Vista 이상을 사용하는 경우 폴더에 심볼릭 링크를 만들 수 있습니다. 예를 들면 다음과 같습니다.

mklink /d C:\pf "C:\Program Files"

c:\pf당신의 program files폴더 가 될 링크를 만들 입니다. 이 트릭을 사용하여 내 경로에서 300자를 깎았습니다.


누군가 관심이 있다면 ...

I find I never really need all those paths at once, so I create a bunch of "initialization" batch files which modify the path accordingly.

For example, if I wanted to do some C++ development in Eclipse, I would do:

> initmingw
> initeclipse
> eclipse

This is also handy for avoiding conflicts between executables with the same name (such as the C++ and D compilers, which both have a make.exe).

My batch files typically look like this:

@echo off
set PATH=C:\Path\To\My\Stuff1;%PATH%
set PATH=C:\Path\To\My\Stuff2;%PATH%

I find this approach relatively clean and have yet to run into any problems with it.


I generally don't have to worry about this (I haven't run into a path size limit - I don't even know what that is on modern Windows systems), but here's what I might do to avoid putting a program's directory in the path:

  • most command line utilities get thrown into a c:\util directory that's on the path
  • otherwise, I'll add a simple cmd/batch file to the c:\util directory that looks something like:

    @"c:\program files\whereever\foo.exe" %*
    

which essentially creates an alias for the command. It's not necessarily perfect. Some programs really insist on being in the path (that's pretty rare nowadays), and other programs that try to invoke it might not find it properly. But for most uses it works well.

But generally, I haven't had to worry about avoiding adding directories to the path.


Another idea: Use DIR /X to determine the short names generated for non-8dot3 file names. Then use these in your %PATH%.

For example, 'C:\Program Files' becomes 'C:\PROGRA~1'.


USe the App Path registry key instead of the path variable for application-specific paths:

http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx


Creating a folder c:\bin adding to your path and hardlinking like you said could shorten the string. Maybe add a variable pf to system vars with value c:\Program Files then replace c:\Program Files with %pf% in path.

Edit:

Create a virtual drive. subst p: "c:\program files"


I wrote and use on a every-time basis a standard stream (stdin/stderr/stdout) & exit code PROXY program (called dispatcher https://github.com/131/dispatcher)

All CLI program i use (node, php, python, git, svn, rsync, plink ...) i'm using are actually the same exe file (around 10kb, that i just name differently), that i put in the same directory. A dummy static clear text file do the "proxy file name to real exe mapping".

Dispatcher use low level Process management win32 API to be absolutly transparent.

Using this software, i only do have ONE additionnal directory set in my PATH for all programs i might use.


I follow these steps to make the entries manageable:

  1. Created different users for different combination of software packages usage. Example: (a) Created a user web for making available all the web development software; (b) Created a user database for making available all the database and data warehousing software packages. Remember some software may create more than one entry. Or sometime I break this into oracle specific and MSSQL specific and oracle specific users. I put MySQL/PostgreSQL, tomcat, wamp, xamp all into the user account webr.

  2. If possible install common packages like office, photoshop, .. as system specific available for all users and special packages as user specific. Of course I had to log into different users and install them. Not all software may provide this option. If "install for this user only" option is not available, install it for the whole system.

  3. I avoid installing programs in to the folder Program File (x86) or in to Program File. I always install into the base directory. For example MySQL 64 bit goes into "C:\mysql64" and MySQL 32 bit goes into "C:\mysql" folder. I always assume adding a suffix 64 only for 64bit software. If no suffix, then it is a 32 bit. I follow the same thing to Java and others. This way my path will be shorter, not including "C:\Program File (x86)". For some software the configuration file may need to be edited to show where exactly the .exe file is. Only program that demands to be installed into "C:\Program File (x86)" will be installed into that folder. Always I remember to shorten the names. I avoid version number like tomcat/release/version-2.5.0.3 such details. If I need to the know version, I create a file by name version and put it into the tomcat folder. In general shorten the link as much as possible.

  4. Include any batch to replace abbreviated link to the path, if all the above steps passed the Windows limit.

Then Log into usage specific (mobile application, or database/data warehousing or web-development.. ..) user and do the relevant tasks.

You can also create virtual windows within windows. As long as you have one licensed OS copy, creating multiple virtual windows with same key is possible. You can put packages specific for a particular task in that machine. You have to launch separate VM each time. Some memory intensive packages like 3D animation movie makers all should be put into the main machine, not into VM as VM will have only a part of the RAM available for its use. It is a pain to boot each VM though.


The solutions above only work if you can trim down your path. In my case, that wasn't really an option, and it was a hassle to have to run a script every time I opened a command prompt. So I wrote a simple script that runs automatically when opening the command prompt, and appends the contents of a text file to your path.

There are also some contexts where having this script run breaks things (say, in a github or cygwin shell), so I also added a file that contains a list of paths that, if the command prompt is started in them, the path variable isn't changed via the startup script that normally updates the path.

@echo off

:: Modify these to the actual paths of these two files
set dontSetupFile=C:\Users\Yams\Dontsetup.txt
set pathFile=C:\Users\Yams\Path.txt

:: Retrieve the current path (for determining whether or not we should append to our path)
set curDir=%cd%

:: Be done if the current path is listed in the dontSetupFile
SetLocal EnableDelayedExpansion
for /F "delims=" %%i in (%dontSetupFile%) do (
    if "%%i"=="%curDir%" GOTO AllDone
)



:: Append the pathFile to our current PATH
set pathAppend=
for /F "delims=" %%i in (%pathFile%) do (set pathAppend=!pathAppend!%%i)

set PATH=%PATH%;%pathAppend%


:: The only way to actually modify a command prompt's path via a batch file is by starting
::   up another command prompt window. So we will do this, however, if this script is
::   automatically called on startup of any command prompt window, it will infinately 
::   recurse and bad things will happen.

:: If we already ran, we are done
if "%yams%"=="onion" GOTO AllDone

:: Otherwise, flag that we just ran, and then start up a new command prompt window
::   with this flag set
set yams=onion

cmd \K set PATH=%PATH%;

:: When that command prompt exits, it will load back up this command prompt window, and
::   then the user will need to exit out of this as well. This causes this window to
::   automatically exit once the cmd it just spawned is closed.
exit()

:: Path is set up, we are done!
:AllDone
@echo on

And Path.txt will look something like

C:\Program Files (x86)\Google\google_appengine;
C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;
C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;
C:\Program Files\Microsoft SQL Server\110\Tools\Binn;
C:\Program Files\Microsoft DNX\Dnvm;
C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit;

While Dontsetup.txt will look something like

C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit
C:\Program Files (x86)\Git\cmd
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin

To make this run automatically on startup, open regedit, navigate to HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Command Processor, then right click on the right and press new -> Multi-String Value. Name it AutoRun. Set it's value to

C:\Users\Yams\setUpPath.bat

or wherever else you stored the batch file above.


Didn't try it, but will splitting PATH in parts work and joining them in final variable work?

Example initially let's say you have something like

PATH={LONGPATH1};{LONGPATH2};....{2048th char}....{LONGPATH_N-1};{LONGPATH_N}

Instead you create:

_PATH1 = {LONGPATH1};{LONGPATH2};....{2048 char}
_PATH2 = {2049th char}...{LONGPATH_N-1};{LONGPATH_N}
rem // may be more parts
PATH = %_PATH1%;%_PATH2%

참고URL : https://stackoverflow.com/questions/4405091/how-do-you-avoid-over-populating-the-path-environment-variable-in-windows

반응형