Windows에서 PATH 환경 변수가 과도하게 채워지지 않도록하려면 어떻게해야합니까?


115

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

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


왜 그렇게 많은 경로를 사용합니까? path는 일반적으로 앱이 extend object / app / lib를 다른 사람과 공유해야 할 때 공통 디렉토리에 사용됩니다. 너무 많이 사용하면 앱 시작 속도가 느려집니다. 사용 방법에 대해 자세히 설명하고 경로 환경 변수를 만들 수 있습니까?
pinichi 2010

1
안녕하세요, 많은 응용 프로그램이 표준 "C : \ Program File \ AppNAme \ ..."을 사용합니다. 제 경우에는이 응용 프로그램의 대부분이 명령 줄 방식으로 실행되거나 다른 응용 프로그램에 액세스 할 수 있어야합니다 ( 예를 들어 모든 Tex 편집자가 존재한다고 예상하는 Miktex의 실행 파일), 따라서 PATH에 있어야합니다. 내 것이 지속될 수 없기 때문에 더 나은 접근 방식을 알고
싶지 않습니다

1
이 도구는 경로를 압축합니다. 결과는 인상적입니다. uweraabe.de/Blog/2014/09/09/the-garbled-path-variable/#more-337
InTheNameOfScience

답변:


84

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

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 : 이 간단한 테스트로 인해 Ben Voigt가 옳다고 믿게됩니다.

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%

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


1
8dot3 형식은 잘 작동하지만 "C : \ Program Files (x86) \ Microsoft Visual Studio 2008 SDK \ VisualStudioIntegration \ Tools \ Sandcastle \ ProductionTools \"와 같이 실제 큰 디렉터리의 경우 너무 크지 않습니다. 조금 절약 할 수있는 또 다른 점은 사용자로서 시스템 경로를 기반으로 PATH 변수를 만들고 다른 디렉터리를 추가 할 수 있다는 것입니다. 이 모든 접근 방식은 "그 문자열 압축"유형이지만 Unix처럼 중앙 집중식 바이너리 디렉토리를 가질 수 있습니까?
mjsr 2010

1
흠, 매우 긴 디렉토리에 대해서는 그 반대가 사실이라고 생각합니다. 디렉토리가 길수록 8dot3 형식을 사용하여 더 많은 문자를 저장합니다. 에서 탐색하기 어려운 경우 입력을 저장하는 데 cmd사용할 수 있습니다 *. 예를 들어 루트에서 dir /x pro*. 8dot3 이름과 함께 원하는 디렉토리가 표시됩니다. 그런 다음을 사용 cd하여 탐색하고 프로세스를 반복하십시오.
Mitch Schwartz

1
UNIX와 관련 하여 Windows $PATH와 매우 유사하게 작동하는 %PATH%것이 있으므로 귀하의 요점이 정확히 무엇인지 모르겠습니다. 일반적으로 UNIX 디렉토리 이름은 Windows보다 짧은 경향이 있으며 결과적으로 $PATH또한 짧은 경향이 있습니다.
Mitch Schwartz

2
고마워요 Mitch, 당신이 제공하는 편집 4는 내가 원했던 것입니다!, 이제 필요한 모든 바이너리가있는 중앙 집중식 폴더를 가질 수 있습니다. 일부 앱에 문제가 있는지 더 자세히 테스트 할 예정입니다
mjsr

2
'편집 4'섹션은 실행 파일에 인수를 전달하는 데 지나치게 복잡합니다. Michael Burr의 답변을 참조하십시오.
Dave Andersen

83

이렇게하면 % 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 변수를 업데이트합니다.


매우 유용 해주셔서 감사합니다 !! 그것은 1990 년에서 1338 년으로 나의 길을 단축 시켰고 모든 것이 여전히 매력처럼 작동합니다! 모든 것을 내 경로에 유지하고 배치 파일을 연결하는 데 너무 많은 시간이 소요될 수 있기 때문에 접근 방식을 선택했습니다. 감사!
ndrizza 2014

2
시간이 지남에 따라 누적 된 내 경로에 존재하지 않는 모든 디렉토리에 대해 알려주기 때문에 유용했습니다.
Nate Glenn

27
Rapid Environment Editor는이를 수행하는 또 다른 방법입니다. 존재하지 않는 디렉토리를 강조하고 "긴 경로를 짧은 경로로 변환"옵션이 있습니다.
Russell Gallop

3
@RussellGallop : 선생님, 정말 멋진 도구입니다.
elo80ka 2014-08-16

1
뒤에 누락 된 닫는 따옴표가 %%~sa있습니다. 나는 대답을 업데이트하려하지만 6 자 변경하지 않는 한 그것은 나를 못하게
zr870

28

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

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

링크를 만들 것이므로 폴더도 마찬가지 c:\pf입니다 program files. 이 트릭을 사용하여 내 경로에서 300자를 줄였습니다.


이것은 부분 경로를 나타 내기 위해 환경 변수를 사용하는 것에 대한 좋은 대안입니다.
porcus 16.04.22

1
이것은 확실히 더 도움이 될,하지만 당신은 더 "정확한"(지원?) 솔루션을 원한다면, 당신은 인스턴스를 대체 할 수 c:\Program Filesc:\Program Files (x86)미리 정의 된 변수를 %ProgramFiles%하고 %ProgramFiles(x86)% tenforums.com/tutorials/... 이 몇 문자 저장 각 , 그러나 PATH를 최대한 활용하기 직전이라면 차이가 될 수 있습니다. 그 문제에 대해 올바른 경로로 확인되는 % pf % 및 % pfx %를 만들 것입니다. 아이디어 주셔서 감사합니다! :)
rainabba

% pf % 및 % pfx %와 같은 변수를 사용할 때의 문제는 심볼릭 링크를 만드는 것과 동일한 문제가 발생한다는 것입니다. 소프트웨어 업데이트는 경로 변수에 항목을 다시 추가 할 수 있습니다. 이와 같은 변수를 사용할 때의 또 다른 문제는 주변에 스크립트를 작성하거나 탐색기에서 찾아 보는 것이 빠르고 쉽지 않다는 것입니다. 내가 설명한 방법을 사용하면 말 그대로 c : \ PF를 열 수 있습니다. Windows는 파일을 폴더처럼 인식하므로 매우 쉽게 그것에 대해 bat 또는 powershell을 작성할 수 있습니다.
bmg002

10

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

한 번에 모든 경로가 실제로 필요하지 않기 때문에 경로를 적절히 수정하는 "초기화"배치 파일을 생성합니다.

예를 들어 Eclipse에서 C ++ 개발을하려면 다음을 수행합니다.

> initmingw
> initeclipse
> eclipse

이것은 같은 이름의 실행 파일 (예 : 둘 다 make.exe가있는 C ++ 및 D 컴파일러) 간의 충돌을 피하는데도 유용합니다.

내 배치 파일은 일반적으로 다음과 같습니다.

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

이 접근 방식은 비교적 깨끗하고 아직 문제가 발생하지 않았습니다.


7

나는 일반적으로 이것에 대해 걱정할 필요가 없습니다 (경로 크기 제한에 부딪히지 않았습니다-현대 Windows 시스템에 무엇이 있는지조차 모릅니다), 여기에 프로그램의 디렉토리를 넣는 것을 피하기 위해 할 수있는 일이 있습니다. 경로:

  • 대부분의 명령 줄 유틸리티 c:\util는 경로에 있는 디렉터리 로 던져집니다.
  • 그렇지 않으면 c:\util다음과 같은 디렉터리에 간단한 cmd / batch 파일을 추가합니다 .

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

본질적으로 명령에 대한 별칭을 만듭니다. 반드시 완벽하지는 않습니다. 일부 프로그램은 실제로 경로에 있어야한다고 주장하며 (요즘에는 매우 드뭅니다)이를 호출하려는 다른 프로그램은 제대로 찾지 못할 수 있습니다. 그러나 대부분의 경우 잘 작동합니다.

그러나 일반적으로 경로에 디렉토리를 추가하는 것을 피하는 것에 대해 걱정할 필요가 없습니다.


이 "경로"를 따라 가기 시작할 때 배치 스크립트는 "CALL [bat]"구문없이 다른 배치 스크립트를 호출 할 수 없습니다. 따라서 전달되거나 실행되지 않는 exe가 bat에서 호출되는지 확인하려면 "php script.php"대신 "call php script.php"를 사용하십시오 (양방향 작동). bat 디스패처는 PATH 이름 충돌을 방지하는 것입니다 (동일한 exe의 여러 버전)
131

@ 131 : '이 "경로"'가 의미하는 바를 설명해 주시겠습니까? 예제의 특정 파일 경로를 의미합니까? 아니면이 답변에서 제안한 일반적인 방법?
OR Mapper

@ORMapper : 131이 '이 "경로"를 따라갈 때'라고 말하면 '이 기술을 사용할 때'를 의미합니다.
Michael Burr

1
당신이 썼 듯이, "그것을 호출하려는 다른 프로그램은 그것을 제대로 찾지 못할 수있다"-예를 들면 : 불행하게도, 예를 들어 NAnt와 같은 빌드 도구에 의해 명령 줄 응용 프로그램에 자동 호출을 던질 수 있습니다. 해결 방법은 앞에 추가 된 명령을 호출하는 cmd /c것이지만 이는 빌드 스크립트가 Windows 전용이됨을 의미합니다 : / 별도의 질문 에서 이에 대해 질문했습니다 .
OR Mapper

5

또 다른 아이디어 : DIR / X를 사용하여 8dot3이 아닌 파일 이름에 대해 생성 된 짧은 이름을 확인합니다. 그런 다음 % PATH %에서 사용하십시오.

예를 들어 'C : \ Program Files'는 'C : \ PROGRA ~ 1'이됩니다.


1
죄송합니다. @Mitch가 이미 제안한 것임을 방금 깨달았습니다. 나는 그에게 +1을 줄 것입니다. :)
Android Eve


2

매번 표준 스트림 (stdin / stderr / stdout) 및 종료 코드 PROXY 프로그램 (디스패처 https://github.com/131/dispatcher 라고 함 )을 작성하고 사용합니다.

내가 사용하는 모든 CLI 프로그램 (node, php, python, git, svn, rsync, plink ...)은 실제로 동일한 exe 파일 (약 10kb, 이름 만 다르게 지정)입니다. 예배 규칙서. 더미 정적 일반 텍스트 파일은 "실제 exe 매핑에 대한 프록시 파일 이름"을 수행합니다.

Dispatcher는 낮은 수준의 프로세스 관리 win32 API를 사용하여 완전히 투명합니다.

이 소프트웨어를 사용하면 내가 사용할 수있는 모든 프로그램에 대해 PATH에 하나의 추가 디렉토리 만 설정되어 있습니다.


1

경로에 추가하는 c : \ bin 폴더를 만들고 말한 것처럼 하드 링크하면 문자열을 줄일 수 있습니다. 값이 c : \ Program Files 인 시스템 vars에 변수 pf를 추가 한 다음 경로에서 c : \ Program Files를 % pf %로 바꿉니다.

편집하다:

가상 드라이브를 만듭니다. subst p : "c : \ 프로그램 파일"


1
경로에 확장 변수가 포함되어 있으면 더 짧아지지 않을 것이라고 생각합니다.
Ben Voigt

0

항목을 관리 가능하게 만들기 위해 다음 단계를 따릅니다.

  1. 서로 다른 소프트웨어 패키지 사용 조합에 대해 서로 다른 사용자를 생성했습니다. 예 : (a) 모든 웹 개발 소프트웨어를 사용할 수 있도록 사용자 웹을 생성했습니다. (b) 모든 데이터베이스 및 데이터웨어 하우징 소프트웨어 패키지를 사용할 수 있도록 사용자 데이터베이스를 생성했습니다. 일부 소프트웨어는 두 개 이상의 항목을 생성 할 수 있습니다. 또는 언젠가 나는 이것을 오라클 특정 및 MSSQL 특정 및 오라클 특정 사용자로 나눕니다. MySQL / PostgreSQL, tomcat, wamp, xamp를 모두 사용자 계정 webr에 넣었습니다.

  2. 가능하면 office, photoshop, ..과 같은 일반 패키지를 모든 사용자가 사용할 수있는 시스템 별 패키지로 설치하고 사용자 별 패키지를 설치하십시오. 물론 다른 사용자로 로그인하여 설치해야했습니다. 모든 소프트웨어가이 옵션을 제공하는 것은 아닙니다. "이 사용자 만 설치"옵션을 사용할 수없는 경우 전체 시스템에 설치하십시오.

  3. Program File (x86) 폴더 나 Program File 폴더에 프로그램을 설치하지 않습니다. 나는 항상 기본 디렉토리에 설치합니다. 예를 들어 MySQL 64 비트는 "C : \ mysql64"로 이동하고 MySQL 32 비트는 "C : \ mysql"폴더로 이동합니다. 나는 항상 64 비트 소프트웨어에 대해서만 접미사 64를 추가한다고 가정합니다. 접미사가 없으면 32 비트입니다. 나는 자바와 다른 사람들에게도 같은 것을 따른다. 이렇게하면 "C : \ Program File (x86)"을 포함하지 않고 경로가 더 짧아집니다. 일부 소프트웨어의 경우 .exe 파일이 정확히 어디에 있는지 표시하기 위해 구성 파일을 편집해야 할 수 있습니다. "C : \ Program File (x86)"에 설치해야하는 프로그램 만 해당 폴더에 설치됩니다. 항상 이름을 줄여야한다는 것을 기억합니다. 나는 tomcat / release / version-2.5.0.3과 같은 버전 번호를 피합니다. 알고있는 버전이 필요하면 이름 버전으로 파일을 만들고 tomcat 폴더에 넣습니다. 일반적으로 가능한 한 링크를 줄이십시오.

  4. 위의 모든 단계가 Windows 제한을 통과 한 경우 경로에 대한 약식 링크를 대체 할 배치를 포함합니다.

그런 다음 용도별 (모바일 애플리케이션, 데이터베이스 / 데이터웨어 하우징 또는 웹 개발 .. ..) 사용자로 로그인하고 관련 작업을 수행합니다.

창 내에 가상 창을 만들 수도 있습니다. 라이센스가 부여 된 OS 사본이 하나만 있으면 동일한 키로 여러 가상 창을 만들 수 있습니다. 특정 작업에 특정한 패키지를 해당 컴퓨터에 넣을 수 있습니다. 매번 별도의 VM을 시작해야합니다. 3D 애니메이션 영화 제작자와 같은 일부 메모리 집약적 패키지는 VM이 ​​사용할 수있는 RAM의 일부만 가질 수 있으므로 VM이 아닌 메인 머신에 모두 넣어야합니다. 하지만 각 VM을 부팅하는 것은 고통 스럽습니다.


0

위의 솔루션은 경로를 줄일 수있는 경우에만 작동합니다. 제 경우에는 실제로 옵션이 아니었고 명령 프롬프트를 열 때마다 스크립트를 실행해야하는 번거로 웠습니다. 그래서 명령 프롬프트를 열 때 자동으로 실행되는 간단한 스크립트를 작성하고 텍스트 파일의 내용을 경로에 추가했습니다.

이 스크립트를 실행하면 작업이 중단되는 컨텍스트 (예 : github 또는 cygwin 셸)도 있으므로 명령 프롬프트가 시작되면 경로 변수가없는 경로 목록이 포함 된 파일도 추가했습니다. 일반적으로 경로를 업데이트하는 시작 스크립트를 통해 변경되지 않습니다.

@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

그리고 Path.txt는 다음과 같습니다.

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;

Dontsetup.txt는 다음과 같습니다.

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

시작시 자동으로 실행되도록하려면 regedit를 열고 HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Command Processor로 이동 한 다음 오른쪽을 마우스 오른쪽 단추로 클릭하고 새로 만들기-> 다중 문자열 값을 누릅니다. 이름을 AutoRun으로 지정합니다. 값을 다음으로 설정하십시오.

C:\Users\Yams\setUpPath.bat

또는 위의 배치 파일을 저장 한 다른 곳에.


0

시도하지 않았지만 부분에서 PATH를 분할하고 최종 변수 작업에 결합합니까?

예를 들어 처음에는 다음과 같은 것이 있다고 가정 해 보겠습니다.

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

대신 다음을 생성합니다.

_PATH1 = {LONGPATH1};{LONGPATH2};....{2048 char}
_PATH2 = {2049th char}...{LONGPATH_N-1};{LONGPATH_N}
rem // may be more parts
PATH = %_PATH1%;%_PATH2%
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.