Windows의 공백 및 괄호 PATH 변수는 배치 파일을 망칩니다.


14

따라서 내 경로 변수 (시스템-> 고급 설정-> 환경 변수-> 시스템-> PATH)는 다음과 같이 설정됩니다.

C:\Python26\Lib\site-packages\PyQt4\bin;
%SystemRoot%\system32;
%SystemRoot%;
%SystemRoot%\System32\Wbem;
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;
C:\Python26\;
C:\Python26\Scripts\;
C:\cygwin\bin;
"C:\PathWithSpaces\What_is_this_bullshit";
"C:\PathWithSpaces 1.5\What_is_this_bullshit_1.5";
"C:\PathWithSpaces (2.0)\What_is_this_bullshit_2.0";
"C:\Program Files (x86)\IronPython 2.6";
"C:\Program Files (x86)\Subversion\bin";
"C:\Program Files (x86)\Git\cmd";
"C:\Program Files (x86)\PuTTY";
"C:\Program Files (x86)\Mercurial";
Z:\droid\android-sdk-windows\tools;

분명히, 개행없이.

PathWithSpaces첫 번째 줄 에는 공백이없고, 두 번째 줄에는 공백이 있고, 세 번째 줄에는 괄호가 있습니다.

이제이 배치 파일의 출력을 확인하십시오.

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\>vcvars32.bat
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>"C:\Program Files (x86
)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
\What_is_this_bullshit_2.0";"C:\Program was unexpected at this time.
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>      set "PATH=C:\Pro
gram Files\Microsoft SDKs\Windows\v6.0A\bin;C:\Python26\Lib\site-packages\PyQt4\
bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\
WindowsPowerShell\v1.0\;C:\Python26\;C:\Python26\Scripts\;C:\cygwin\bin;"C:\Path
WithSpaces\What_is_this_bullshit";"C:\PathWithSpaces 1.5\What_is_this_bullshit_1
.5";"C:\PathWithSpaces (2.0)\What_is_this_bullshit_2.0";"C:\Program Files (x86)\
IronPython 2.6";"C:\Program Files (x86)\Subversion\bin";"C:\Program Files (x86)\
Git\cmd";"C:\Program Files (x86)\PuTTY";"C:\Program Files (x86)\Mercurial";Z:\dr
oid\android-sdk-windows\tools;"

또는 구체적으로는

\What_is_this_bullshit_2.0";"C:\Program was unexpected at this time.

그래서,이 헛소리는 무엇입니까?

구체적으로 특별히:

  • 따옴표로 올바르게 이스케이프되지만 공백이없는 경로의 디렉토리
  • 따옴표로 올바르게 이스케이프되고 공백이 있지만 괄호가없는 경로의 디렉토리 = fine
  • 따옴표로 올바르게 이스케이프되고 공백이 있고 괄호 = ERROR가있는 경로의 디렉토리

무슨 일이야? 이 문제를 어떻게 해결할 수 있습니까? 내 도구가 여전히 해결 방법으로 작동하도록 접합 지점에 의지 할 것입니다. 그러나 이에 대한 통찰력이 있으면 알려주십시오. :)


당면한 문제에 대한 나의 이해를 바탕으로, 위의 대답은 정답이며 SET은 명령이며 PATH는 인수의 일부이며 균형은 새로운 PATH 문자열입니다. 따라서 IMO는 드물게 문서화 된 것이 아니라 모호한 경우와 비슷합니다. 방금이 문제에 몇 시간을 보냈습니다.
David A. Grey

답변:


13

"블록"내부의 줄에 이스케이프 처리되지 않은 괄호가있는 경우 (구분 기호로 괄호를 사용하는 경우) 발생할 수 있습니다.

일반적으로 지연 확장을 설정하여 문제를 해결하고 !var!대신 변수를 사용할 수 있습니다 %var%. 코드를 보지 않고도 더 많은 조언을 할 수는 없습니다.



13

중 (a)는이해야 되지 는 MS Windows가 PATH 환경 변수에 어떤 인용 수 (PATH 명령) 또는 (b) 다음 전체 표현식 주위의 따옴표가 있어야한다 (SET 명령) . 불행히도, 이것은 인용 부호가 사용되면 변수의 값에 포함된다고 진술하지만 (MS)에 의해 잘 문서화되어 있지 않습니다 (Windows XP Command Line Reference) .

$ SET BLAH="blah blah(1)"
$ ECHO %BLAH%
"blah blah(1)"
$ SET BLAH=blah blah(1)
$ ECHO %BLAH%
blah blah(1)

이로 인해 일관성이 없어 진단하기 어려운 문제가 발생할 수 있습니다. 예를 들어, 경로에 "C : \ Python27"이 포함 된 경우 시스템은 " 'python'이 내부 또는 외부 명령, 실행 가능한 프로그램 또는 배치 파일로 인식되지 않습니다"라고 말합니다. 파이썬을 실행하려고 할 때. 그러나 일부 라이브러리 여전히 사용 가능할 수 있습니다.

공백이나 괄호를 "탈출"할 필요 는 없습니다 . 특수 문자를 이스케이프해야하는 경우 변수 이름을 포함 하여 전체 표현식 주위에 따옴표를 넣으십시오 .

SET "PATH=%PATH%;C:\Program Files (x86)\path with special characters"

또는 괄호도 사용할 수 있습니다.

(SET VAR=can't contain ampersand, parentheses, pipe, gt or lt)

큰 따옴표는 쌍을 이루어야합니다.

(SET VAR=illegal characters!@#$%^*_-+={}[]\:;""',./?)
echo %VAR%
illegal characters!@#$%*_-+={}[]\:;""',./?

그러나 유효한 경로 이름 인 문자가 없을 수 있으며 SET 명령에 문제가 발생할 수 있습니다.



1
MS-Windows를 의미 할 때 실제로 MS-DOS를 작성했으며 명령은 MS-Windows 용이었습니다. OP는 MS-Windows에 관해 물었다. 그래서 왜 당신은 그것을 모르는 MS-DOS라고 부릅니다. 귀하의 링크조차도 NT라고 말했습니다 (이것은 Windows입니다. 이전에는 9X와 NT였습니다. 이제는 NT입니다). Windows와 MS-DOS는 서로 다른 두 운영 체제입니다. Windows 명령 프롬프트에서 실수로 DOS를 호출 한 것을 보았지만 그 호출이 잘못되었습니다.
barlop

@ barlop은 물론 정확합니다. 편집 해 주셔서 감사합니다. Windows-95까지 Windows는 DOS를 기반으로 구축 된 응용 프로그램이었습니다. winDOS 에서 명령 을 입력하여 Windows를 시작할 수 있습니다. 실제로 Windows-3.1 이전에는 Zork 및 WordStar와 같은 모든 것이 DOS 응용 프로그램이었습니다. 그런 다음 Windows-98부터는 DOS가 없었습니다. 그러나 저와 같은 오래된 타이머는 여전히 CMD 쉘을 DOS 쉘이라고 잘못 생각합니다. 혼란을 드려 죄송합니다. 답변의 의도를 명확히 해주셔서 다시 한 번 감사드립니다.
Mark Mikofski

@MarkMikofski 사실 Windows 9X (95 / 98 / ME)는 DOS에서도 구축되었습니다. 예를 들어 bootGUI = 0과 같은 일부 파일 (어쩌면 msdos.sys)을 편집하고 창로드를 중지 할 수 있습니다 tokyopc.org/newsletter/1996/08/msdosed.html 그런 다음 거기에서 창을로드 할 수 있는지 여부는 ' 알지 그리고 Win9X 부팅 디스크는 DOS로 간주됩니다. 그들이 무엇을 말하고 있는지 알고있는 오래된 타이머는 대개 Windows 명령 프롬프트 DOS를 호출하는 실수를 한 사람들입니다. 그리고 그것이 DOS가 아니라는 것이 가장 단호한 첫 번째 사람들입니다.
barlop

1
당신 조언 을 시도 했습니까 (SET PATH=%PATH%;C:\Program Files (x86)\path with special characters)? 완전히 틀렸다!
JosefZ

2

Microsoft는 " 괄호가 포함 된 명령 쉘 스크립트 실행 중 오류 발생"에 문제점을 설명합니다 .

그들이 제안하는 해결책은 지연 확장을 사용하는 것입니다.

SETLOCAL ENABLEDELAYEDEXPANSION
SET VAR=string containing ( and ) ...
IF "y" == "y" (
    ECHO !VAR! %VAR%
)
ENDLOCAL

를 사용하지 않고 if 블록에 경로를 설정 SET PATH=하려면 PATH명령을 사용해야합니다 .

SET AddToPath=C:\Program Files (x86)\Whatever

SETLOCAL ENABLEDELAYEDEXPANSION
IF "%X%" == "%Y%" (
    ECHO Adding !AddToPath! to path !PATH!
    PATH !AddToPath!;!PATH!
)

다른 변수의 경우 다른 해결책은 따옴표를 사용하는 것이지만 전체를 둘러 쌀 수 있습니다.

SET "MyVar=C:\Program Files (x86)\Whatever"

1

그의 답변에서 Joey는 말합니다

"블록"내부의 줄에 이스케이프 처리되지 않은 괄호가있는 경우 (구분 기호로 괄호를 사용하는 경우) 발생할 수 있습니다.

그리고 그것은 사실입니다. 이스케이프 처리되지 않은 괄호가 있으면 잘 빠져 나갑니다. 그것이 내가 한 일입니다. 나는 바꿨다

set PATH=some_path;%PATH%

set PATH="some_path;%PATH%"

그리고 이것은 문제를 해결했습니다.


2
아니. 당신이 사용해야합니다set "PATH=some_path;%PATH%"
JosefZ

1

나는 비슷한 것을 경험했다. Microsoft는 여기에 문제를 설명합니다. http://support.microsoft.com/kb/329308

기본적으로 시스템-> 고급 설정-> 환경 변수-> 시스템-> 경로를 통해 경로 변수를 변경하는 대신 시도하십시오.

My Computer->Manage->Computer Management (local)-> Properties-> Advanced-> Environment variables-> Settings

1

Windows 8에서는 이러한 방법으로 거의 성공하지 못했습니다. 괄호가 작동하지 않고 따옴표가 작동하지만이 방법으로 수정 한 "경로"는 실행 파일을 찾는 데 사용되는 경로가 아니라 cmd여전히 창을 열 때 상속 된 시스템 경로를 사용하는 것 같습니다.

예 : 프로세서 아키텍처를 결정한 후 PATH 환경 변수에 몇 가지 경로를 추가하려고합니다. 실제로 배치 파일이 실행되는 동안 필요하기 때문에 임시로 추가해도 작동합니다. 그러나 그것은 심지어 작동하지 않습니다.

echo %path%cmd시작 시 시스템 경로를 표시합니다 .

set path="%path%;%programfiles(x86)%\company\program\subdir"작동하지만 이제는 %path%따옴표로 묶은 모든 것을 포함하고 하위 디렉토리에서 프로그램을 다른 곳에서 실행하려고하면 실패합니다. 따옴표 대신 괄호를 사용하면 효과 가 없습니다 .

내가 주목 한 또 다른 점은 대화식으로 입력하면 동일한 명령이 작동 cmd하지만 배치 파일에서는 발생하지 않는다는 것입니다. 무섭습니다. 또 다른 이상한 점은 환경 변수 값의 마지막 문자가 간헐적으로 손실된다는 것입니다! 또 다른 불일치는 타사 프로그램과 관련이 있습니다. 일부는 %var%매개 변수로 처리 할 수 ​​있고 다른 일부는 처리 할 수 없습니다.


1

fromFile 변수로 설정 한 값을 큰 따옴표로 묶을 때까지 Win8에서 다음 작업을 수행하는 데 큰 어려움이있었습니다. 그로부터 fromFile에 괄호가있는 파일 이름이 포함 된 경우 toFile 변수를 생성하기 위해 문자열 대체를 시도한 다음 행이 실패했습니다. (각 CALL 인스턴스의) 구문 분석 시간 대신 실행 시간에 변수를 평가하기 위해 지연 확장을 사용합니다.

::-- BATCH file that creates an *_576_5.* file from an *_640_t.* one (copying it)
::-- Author: George Birbilis (http://zoomicon.com)
::-- Credits: String replacement based on http://www.dostips.com/DtTipsStringManipulation.php

@ECHO OFF

::-- Loop for all files recursively --::

FOR /R %%f in (*_640_t.*) DO CALL :process %%f

ECHO(
PAUSE

GOTO :EOF

::-- Per-file actions --::

:process

:: Display progress...
::ECHO Processing %*
<nul (set/p dummy=.)

SETLOCAL ENABLEDELAYEDEXPANSION
SET fromFile="%*"
SET toFile=!fromFile:_640_t=_576_t!

IF NOT EXIST %toFile% CALL :generate %fromFile% %toFile%

GOTO :EOF

::-- Generate missing file --::

:generate

ECHO(
ECHO COPY %*
COPY %*

::PAUSE

GOTO :EOF
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.