Windows 배치 파일에서 하이픈은 무엇을 의미합니까?


1

특히 다음 줄의 하이픈을 이해하는 데 문제가 있습니다 .

if not -%1-==-- echo Argument one provided
if -%1-==-- echo Argument one not provided & exit /b

변수가 존재하는지 또는 정의되었는지 테스트하기 위해 기본적으로 두 가지 방법이 있습니다 .

IF DEFINED MyVar (ECHO MyVar IS defined) ELSE (ECHO MyVar is NOT defined)

IF "%MyVar%"=="" (ECHO MyVar is NOT defined) ELSE (ECHO MyVar IS defined)

따라서 (1) % 1 인수 주위의 하이픈과 (2) == 기호 뒤의 하이픈은 무엇을 의미합니까?


1
귀하의 의견 중 하나는 % %를 언급했는데 배치 명령 줄 매개 변수 % 1 % 2 % 3이 아닌 % % f와 같은 배치 파일의 for 루프에서 사용됩니다. for %1 in (*.*) do @echo %1배치 파일 내에서 % %를 사용하지만 배치 매개 변수 (btw는 배치 파일에만 있음)를 사용하는 명령문의 경우 명령 줄 에서 배치 파일에서 수행하는 것이 모호합니다. , % 2 etc
barlop

친애하는 midnite : 2015 년입니다. 왜 여전히 배치 스크립팅만큼 열악한 프로그래밍 언어를 사용하고 있습니까? VBScript, JScript, PowerShell 또는 다른 많은 선택 사항 중 하나로 전환 할 수 있습니다 .
잊을 수없는

"그러나 이것들은 사용하기 전에 스크립팅 언어 인터프리터를 설치해야합니다."-더 배우는 데 아무런 해가 없습니다. esp는 대부분의 PC에서 기본적으로 실행됩니다. ;-)
midnite

1
@midnite 나는 배치로 추측 할 수있는 문제의 수에는 한계가 있다고 생각합니다. 따라서 몇 년 동안 묻고 삐걱 거리며 배웠습니다. 그리고 어떤 언급에도 쓰지 않은 것을 알아 낸 천재가있는 것처럼 보입니다. 정말 어려워 질 때. 예를 들어 .. dave benham과 jeb .. 나는 여기 두 게시물과 dostips 포럼에 있다고 생각합니다. 그리고 참고로 당신이 DOS를 실행했을 때 원래 vfrazee.com/ms-dos/6.22/help 가 있습니다. HELP.COM (예를 들어 IF를 클릭 한 다음 예를 클릭 할 수 있음)이 있으며 ss64.com/nt
barlop

1
이 작은 C 프로그램은 프로그램 escapign 문제를 인용에 도움이 매개 변수에 문제를 일으킬 방법을 보여 도움을 줄 수 superuser.com/questions/944745/sed-command-with-apostrophe/... 그리고 만약 당신이 깊은 너트 가면, 다음 젭 및 dbenham가 쓴 배치 인터프리터 작동 방식에 대한 게시물. 참조가 아닌 테스트를 통해 발견 stackoverflow.com/questions/4094699/…
barlop

답변:


6

이걸 고려하세요

C:\>if not -%1-==-- echo Argument one provided
Argument one provided

C:\>if not P%1P==PP echo Argument one provided
Argument one provided

빼기 / 하이픈 문자는 단순히 빈 값을 쉽게 지정하는 데 사용됩니다. 이 특정 기호는 해당 표현에서 특별한 의미가 없습니다. 다른 비 특수 문자처럼 취급됩니다.

공백을 추가하여 ==연산자가 주변 문자로 수정 되지 않음 을 분명히 할 수 있습니다

C:\>if not P%1P == PP echo Argument one provided
Argument one provided

일반적으로 더 많은 사람들이 더 빨리 이해할 수있는 기존의 접근 방식 (예 : 따옴표 사용)을 사용하는 것이 좋습니다.

C:\>if not "%1"=="" echo Argument one provided
Argument one provided

DOS와 아마도 초기 버전의 Windows에서는 따옴표를 사용하는 데 문제가 있었으며 사람들이 인쇄 가능한 문자를 사용하는 방식으로이 문제를 믿었습니다. 예를 들어 % 1에 따옴표가 포함 된 경우를 시도하지 않았습니다.


내가 참조. 매우 감사합니다. 따라서 본질적으로 변수 앞뒤에 두 문자를 연결하는 것을 의미합니까? OTOH, defined키워드를 사용하여 매개 변수가 있는지 확인했습니다. 모두 IF DEFINED %1와는 IF DEFINED %%1작동하지 않는 것 같다. 힌트 좀 주실 래요?
midnite

"빼기 / 하이픈 문자는 단순히 빈 값의 지정을 단순화하는 데 사용됩니다"<--- "단순화"라는 단어는 아마도 '단순화하지 않는 것'을 사용하는 좋은 단어가 아닐 것입니다. 단순화 된 것이 무엇이든간에). 그러나 아시다시피, 인수가 주어지지 않은 경우 오류가 발생하지 않습니다.
barlop

@ barlop : 의견 주셔서 감사합니다. 답변이 수정되었습니다.
RedGrittyBrick은

편집은 잘되었지만 마지막에는 "DOS와 초기 버전의 Windows에서는 따옴표를 사용하는 데 몇 가지 문제가 있음을 기억합니다"<-여전히 있습니다. "% 1"을 다시 사용하면 내 대답을 볼 수 있습니다. 나는 처음에 따옴표가 % 1 부근에서 훌륭하다고 말한 다음 슈퍼 캣 (supercat)으로 댓글을 달고 수정했습니다.
barlop

"예를 들어 % 1에 따옴표가 포함 된 경우에는 시도하지 않았습니다." <-사용자가 제공하고 "% 1"을 (를)하지 않으면 괜찮습니다. 사용자가 제공하고 "% 1"(을)를 추가하면 괜찮지 않습니다
barlop

4

그것은 % 1이 비어있을 때 % 1 SQL 주입처럼, 그것은 값으로 대체됩니다 변수가 아니기 때문에 그것이 파괴에서 배치 파일을 방지하기 위해 주위에 % 1을 사용하여 뭔가를 넣어 때 중요 배치에 주입의 예 , 그리고 값이 아무것도 아니며 % 1이 IF에 있으면 코드가 손상됩니다. if %1==""되고 if == ""오류가 발생합니다.

정의 된 값이 % 1에서 작동하지 않는 이유는 % 1이 변수가 아닌 값이므로 정의 된 값이 작동하지 않습니다. % 1이 비어있는 코드의 경우 % 1을 아무것도 대체하지 않아도 깨지지 않는 코드가 필요합니다. 시도 if "%1"=="" 또는 시도if [%1]==[]

-% 1은 약간 혼란스러워 보이지만 나에게 좋은 관례는 아닙니다! 기술적으로 당신이 할도 수 if a%1==a%1 또는 if %1a==%1a하지만 규칙은 경향이있다[]

따옴표 나 [] 또는 모든 문자를 사용할 수 있습니다. 그러나 supercat이 주석에서 지적했듯이 인용 부호는 % 1 주위에 좋은 생각이 아닙니다. (% 1에 공백이 포함되어 있기 때문에 사용자는 % 1에 전달되는 항목에 따옴표를 포함하고 % 1과 배치 파일에 공백이 있으면 % 1 주위에 따옴표를 넣으면 따옴표가 취소됩니다. 인용되지 않은 공간에 오류가 발생합니다).

명령 행에서 IF를 수행하고 변수를 테스트하지 않은 경우 % 1이없고 []가 필요하지 않습니다. 당신은 말할 것 IF "a b c"=="a b c" echo a 또는 IF a==b echo a 배치 파일에 다음 자주 % 1 주위에 따옴표를 사용하는 대신 % 1이 있고, 경우, 예를 들어 주위 예를 들어, 하나 또는 두 개의 문자를 사용 [%1]하고 공간을 보존해야하는 경우 따옴표를 사용하고는 % 아니다 1 egeg IF [%1]==[a]또는 IF [%1]==["a b"] echo a하지 마십시오 "%1". % 1에 이미 따옴표가 취소 될 따옴표가있을 수 있으며 % 1에 공백이 있으면 if 문이 끊어집니다.

명령 행에 있고 변수를 테스트하는 경우 변수에 따옴표가 있는지 여부에 따라 다릅니다. 내용을 볼 수 있습니다.

변수에 공백이 있고 따옴표를 포함하지 않을 수 있습니다.

따라서이 특정 명령 행 사례에서 % a % 주위에 따옴표를 두는 것은 큰 따옴표가 아니며 "a b"에 대해 테스트하려는 경우 % a % 주위에 따옴표를 사용해야합니다.

C:\>set a=a b

C:\>echo %a%
a b

C:\>IF %a%=="a b" echo sdf
b=="a b" was unexpected at this time.

C:\>IF "%a%"=="a b" echo sdf
sdf

So ^^^ we want "%a%"

% a %에 따옴표가 포함 된 경우 다른 경우입니다.

C:\>set a="a b"

C:\>echo %a%
"a b"

C:\>IF %a%=="a b" echo a
a

C:\>IF "%a%"=="a b" echo a
b""=="a b" was unexpected at this time.

C:\>

^^^^ So there we want %a% without quotes around it.

변수 또는 매개 변수에 따옴표가 포함되어 있는지 여부는 모두 문제입니다. % 1에 공백이 있으면 따옴표가 포함됩니다. 따라서 % 1을 "a b"와 비교하면 w는 "% 1"을 수행하지 않습니다. 그리고 % 1에 따옴표가 없으면 공백이 포함되지 않으므로 "% 1"을 (를) 사용하지 않으므로 "% 1"을 (를) 원하지 않을 것입니다. 따라서 % 1에 공백이 있으면 % 1 안에 따옴표가 있고 공백은 이미 유지됩니다.

나는 supercat의 의견에 비추어 아래를 건너 뛰었습니다. 그리고 위의 게시물에 더 추가했습니다.

예를 들어 []를 사용하면 공백이 유지되지 않기 때문에 따옴표는 []가 아닌 % 1 또는 A 또는-와 같은 문자가 가장 좋습니다.

C : \> if [dab] == [dab] echo sdf

현재로서는 예상치 못한 일이었습니다.

if "d a b"그것이 효과가 있다고 말하십시오 . 그래서 if "%1"같은 다른 문자 (들)보다 낫다 if [%1]거나 a%1a또는-%1


2
%1인수가 따옴표를 포함하는 경우 공백이 포함 된 것으로 확장 되는 유일한 방법 입니다. 이 경우 %1따옴표로 묶으면 동작이 깨져서 다른 것으로 둘러 쌀 수 있습니다.
supercat

2
인용 된 인수에 공백이 있으면 어떻게됩니까?
supercat

1
@ supercat 아 아, 잘 발견했다. if "" 2""==""2"" echo a실패합니다. 그리고 아무도 모른다면 .. ""인용을 켜고 끄는 효과가있을 것이다.
barlop

1
@midnite 그것은 당신이 고급 언어로 볼 수있는 연결과 약간 유사하지만, 기능적으로는 Java와 같은 cos가 아니라고 생각합니다. cmd "asdf""asdf"와는 달리 두 개의 개별 객체를 결합하지 않습니다. 첫 번째 "는 공백과 다른 문자가 유지되는 모드를 켜는 것을 의미합니다. 다음"은 해당 모드를 끄는 것을 의미합니다. 다음은 켭니다. 그래서 당신은 "asdf을 asdf을"을 말하거나 말할 수 asdf" "asdf 그래서 2""너무 힘들 보지한다. (그러나 때때로 cmd / batch가 어떻게 작동하는지 알아내는 것은 까다 롭습니다)
barlop

1
@midnite는 또한 배치 파일 (일반적으로)이 문자열과 숫자를 구별한다고 의심하지만 명령 내의 일부 명령이나 기능은 그렇지 않습니다. 2가 숫자인지 문자열인지는 해석에 달려 echo 2있습니다. 2를 문자열로 변환하지 않는다고 말하면 됩니다. 나는 컴퓨터로 기술적으로 모든 문자가 인코딩되지 않습니다 (문자를 말하지 않을 것). 어떤 사람들은 따옴표가 있거나없는 경우 프레젠테이션을보고 그에 따라 숫자 (계산 용) 또는 문자열 (알파벳순으로 정렬)로 취급 할 수 있습니다. 또는 인코딩 된 글리프와 마찬가지로 숫자 또는 문자열입니다.
barlop

1

확실하게 알 수 없으므로 단순화 할 수 있는지 살펴 보겠습니다.

배치 파일 %1이 명령 행에 값 을 수신하고 "cat"또는 "dog"인지 확인하려고한다고 가정하십시오. 당신은 그것을 테스트 할 수 있습니다 :

if %1 == cat goto CAT
if %1 == dog goto DOG
REM Default: Complain about no dog or cat
goto OOPS
:CAT
echo I'm a cat!
REM Successful, so skip to end
goto END
:DOG
echo I'm a dog!
goto END
:OOPS
echo I didn't see a cat or dog!
REM This just falls through to the end
:END

%1 고양이 나 개 (개라고합시다)의 텍스트로 바뀌므로 인터프리터는 실제로 이것을 본다 :

if dog == cat goto CAT
if dog == dog goto DOG

그러나 스크립트를 실행하는 사람이 명령 행에 값을 포함하지 않은 경우 해석기는 다음을 볼 수 있습니다.

if  == cat goto CAT
if  == dog goto DOG

잘못된 구문이며 오류가 발생합니다. 따라서 규칙은 하나 이상의 문자를 포함하고 변수가 없는지 먼저 테스트하는 것입니다.

if %1* == * goto OOPS
REM If no value passed in, this is seen as  if * == *  which evaluates to true
if %1 == cat goto CAT
if %1 == dog goto DOG
goto END
:CAT
echo I'm a cat!
goto END
:DOG
echo I'm a dog!
goto END
:OOPS
echo You were supposed to include a type of pet!
:END

%1아무 것도 평가되지 않으면 구문을 올바르게 유지하기 위해 추가 문자가 여전히 존재합니다. 내가 사용 *하지만, 따옴표 또는 외침 또한, 일반적인처럼 "%1"%1!뿐만 아니라, 하이픈, 같은 --%1또는 -%1-등 ..

이봐, 난 아직도이 모든 것을 기억할 수 없어. :-) 이게 도움이 되길 바란다!


"하지만 스크립트를 실행하는 사람이 변수를 포함하지 않았다면"<-당신은 "값"을 의미 할 수 있습니다. 데이터를 전달하는 중일 수 있습니다. 그리고 그것이 어떻게 전달되는지에 관해서는 (더 고급 언어를 프로그래밍 할 때 '값으로 전달'또는 '참조로 전달'을 가질 수 있습니다. 이것이 주입에 의해 전달되었다고 말할 것입니다!
barlop

" '변수가 아닌 값'을 의미 할 수 있습니다." 맞아!
furry_marmot
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.