배치 파일에서 매개 변수가 비어 있는지 테스트하는 적절한 방법은 무엇입니까?
변수 설정 여부를 테스트해야 합니다. 가지 매번 할 것 요.%1
다음과 같은 인용문으로 둘러싸여 있습니다.%1
"c:\some path with spaces"
.
IF NOT %1 GOTO MyLabel // This is invalid syntax
IF "%1" == "" GOTO MyLabel // Works unless %1 has double quotes which fatally kills bat execution
IF %1 == GOTO MyLabel // Gives an unexpected GOTO error.
이 사이트에 따르면 지원되는 것은 다음과 같습니다.IF
그래서 방법이 없네요.
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command
업데이트: 2020년 10월 25일에 승인된 답변을 괄호 사용에서 칠데 사용으로 업데이트했습니다.칠드는 안전할수록 좋다고 다들 말합니다.칠드가 더 복잡해 보이고 용도가 불분명해서 조금 당황스럽지만 그래도 바꿨어요.
따옴표 대신 대괄호를 사용합니다.
IF [%1] == [] GOTO MyLabel
괄호는 안전하지 않습니다.대괄호만 사용합니다.
다음을 사용할 수 있습니다.
IF "%~1" == "" GOTO MyLabel
외부 인용문 세트를 제거합니다.일반적으로 각 괄호를 사용하는 것보다 신뢰성이 높은 방법입니다.변수에 공백이 있어도 동작하기 때문입니다.
반(半) 해결 방법 중 입니다.%1
delayed와 확장을 합니다.합니다.어떤 콘텐츠에도 항상 안전합니다.
set "param1=%~1"
setlocal EnableDelayedExpansion
if "!param1!"=="" ( echo it is empty )
rem ... or use the DEFINED keyword now
if defined param1 echo There is something
이것의 장점은 param1을 다루는 것이 절대적으로 안전하다는 것입니다.
param1의 설정은 많은 경우에 유효합니다.
test.bat hello"this is"a"test
test.bat you^&me
하지만 그것은 여전히 다음과 같은 이상한 내용으로 실패한다.
test.bat ^&"&
존재에 대한 100% 정답을 얻을 수 있다.
검출할 수 있습니다.%1
비어 있지만 일부 콘텐츠에서는 콘텐츠를 가져올 수 없습니다.
은 또한 하는 데에도 도움이 .%1
하나와 하나가 있다.""
.
이 기능은, 다음의 기능을 사용하고 있습니다.CALL
명령어를 사용하여 배치파일을 중단하지 않고 실패합니다.
@echo off
setlocal EnableDelayedExpansion
set "arg1="
call set "arg1=%%1"
if defined arg1 goto :arg_exists
set "arg1=#"
call set "arg1=%%1"
if "!arg1!" EQU "#" (
echo arg1 exists, but can't assigned to a variable
REM Try to fetch it a second time without quotes
(call set arg1=%%1)
goto :arg_exists
)
echo arg1 is missing
exit /b
:arg_exists
echo arg1 exists, perhaps the content is '!arg1!'
내용을 가져오는 데 100% 방탄 기능을 사용하려면 "가장 이상한 명령줄 매개 변수조차 받는 방법"을 참조하십시오.
IF에서 /?:
Command Extensions가 네이블로 되어 있는 경우 IF는 다음과 같이 변경됩니다.
IF [/I] string1 compare-op string2 command IF CMDEXTVERSION number command IF DEFINED variable command
......
정의된 조건은 환경 변수 이름을 사용하고 환경 변수가 정의된 경우 true를 반환한다는 점을 제외하고 EXISTS와 동일하게 작동합니다.
불행하게도 나는 내가 직접 써야 했던 현재의 답변에 대해 논평하거나 투표할 충분한 평판을 가지고 있지 않다.
원래 OP의 질문은 "파라미터"가 아닌 "변수"로 되어 있었는데, 이는 특히 공백 변수를 테스트하는 방법을 검색하기 위한 구글의 1번 링크였기 때문에 매우 혼란스러웠다.원래 답변 이후 Stephan은 올바른 용어를 사용하기 위해 원래 질문을 편집했지만, 저는 답변을 삭제하는 대신 혼란을 해소하기 위해 남겨두기로 했습니다. 특히 Google이 변수를 위해 여전히 사람을 보내는 경우:
%1은 VARAB가 아닙니다LE! 커맨드 라인 파라미터입니다.
매우 중요한 차이점입니다.변수가 아닌 명령줄 매개 변수를 참조하는 숫자 뒤에 있는 단일 백분율 기호.
변수는 set 명령을 사용하여 설정되며, 2% 기호(이전 및 이후)를 사용하여 호출됩니다.예: %myvar%
빈 변수를 테스트하려면 다음과 같이 "정의되지 않은 경우" 구문을 사용합니다(변수에 대한 명령에는 백분율 기호가 명시적으로 필요하지 않음).
set myvar1=foo
if not defined myvar1 echo You won't see this because %myvar1% is defined.
if not defined myvar2 echo You will see this because %myvar2% isn't defined.
(커맨드 라인 파라미터를 테스트하려면 jamesdlin의 답변을 참조할 것을 권장합니다.)
사용할 수 있습니다.
if defined (variable) echo That's defined!
if not defined (variable) echo Nope. Undefined.
배치 파일에서 변수를 테스트하려면 "IF DEFINED variable 명령"을 사용하십시오.
단, 배치 파라미터를 테스트하는 경우 까다로운 입력('1 2' 또는 ab^>cd 등)을 피하기 위해 아래 코드를 시험해 보십시오.
set tmp="%1"
if "%tmp:"=.%"==".." (
echo empty
) else (
echo not empty
)
이 작은 배치 스크립트는 유효한 것이 많기 때문에 여기에 있는 답변을 바탕으로 작성했습니다.같은 형식을 따르는 한 자유롭게 추가해 주세요.
REM Parameter-testing
Setlocal EnableDelayedExpansion EnableExtensions
IF NOT "%~1"=="" (echo Percent Tilde 1 failed with quotes) ELSE (echo SUCCESS)
IF NOT [%~1]==[] (echo Percent Tilde 1 failed with brackets) ELSE (echo SUCCESS)
IF NOT "%1"=="" (echo Quotes one failed) ELSE (echo SUCCESS)
IF NOT [%1]==[] (echo Brackets one failed) ELSE (echo SUCCESS)
IF NOT "%1."=="." (echo Appended dot quotes one failed) ELSE (echo SUCCESS)
IF NOT [%1.]==[.] (echo Appended dot brackets one failed) ELSE (echo SUCCESS)
pause
아래 코드로 테스트해 봤는데 괜찮습니다.
@echo off
set varEmpty=
if not "%varEmpty%"=="" (
echo varEmpty is not empty
) else (
echo varEmpty is empty
)
set varNotEmpty=hasValue
if not "%varNotEmpty%"=="" (
echo varNotEmpty is not empty
) else (
echo varNotEmpty is empty
)
주로 사용하는 것은 다음과 같습니다.
IF "%1."=="." GOTO MyLabel
%1이 비어 있는 경우 IF는 "."과 "."을 비교하고 "."는 true로 평가합니다.
은 " " "의 입니다.double-quotes
/""
길이를 테스트할 수 있습니다.
set ARG=%1
if not defined ARG goto nomore
set CHAR=%ARG:~2,1%
if defined CHAR goto goon
두 를 맞춥니다.double-quotes
:
if ^%ARG:~1,1% == ^" if ^%ARG:~0,1% == ^" goto blank
::else
goto goon
여기 플레이할 수 있는 배치 스크립트가 있습니다.빈 줄을 잘 잡는 것 같아요.
이것은 예에 불과합니다.스크립트에 따라 위의 2단계(또는 3단계)를 커스터마이즈하면 됩니다.
@echo off
if not "%OS%"=="Windows_NT" goto EOF
:: I guess we need enableExtensions, CMIIW
setLocal enableExtensions
set i=0
set script=%0
:LOOP
set /a i=%i%+1
set A1=%1
if not defined A1 goto nomore
:: Assumption:
:: Empty string is (exactly) a pair of double-quotes ("")
:: Step out if str length is more than 2
set C3=%A1:~2,1%
if defined C3 goto goon
:: Check the first and second char for double-quotes
:: Any characters will do fine since we test it *literally*
if ^%A1:~1,1% == ^" if ^%A1:~0,1% == ^" goto blank
goto goon
:goon
echo.args[%i%]: [%1]
shift
goto LOOP
:blank
echo.args[%i%]: [%1] is empty string
shift
goto LOOP
:nomore
echo.
echo.command line:
echo.%script% %*
:EOF
이 고문 테스트 결과:
.test.bat :: "" ">"""bl" " "< "">" (")(") "" :: ""-" " "( )"">\>" ""
args[1]: [::]
args[2]: [""] is empty string
args[3]: [">"""bl" "]
args[4]: ["< "">"]
args[5]: [(")(")]
args[6]: [""] is empty string
args[7]: [::]
args[8]: [""-" "]
args[9]: ["( )"">\>"]
args[10]: [""] is empty string
command line:
.test.bat :: "" ">"""bl" " "< "">" (")(") "" :: ""-" " "( )"">\>" ""
정리하면:
set str=%~1
if not defined str ( echo Empty string )
이 코드는 %1이 " 또는 " 또는 비어 있는 경우 "빈 문자열"을 출력합니다.현재 잘못된 답변에 추가했습니다.
스크립트 1:
입력("Remove Quotes.cmd" "이것은 테스트입니다")
@ECHO OFF
REM Set "string" variable to "first" command line parameter
SET STRING=%1
REM Remove Quotes [Only Remove Quotes if NOT Null]
IF DEFINED STRING SET STRING=%STRING:"=%
REM IF %1 [or String] is NULL GOTO MyLabel
IF NOT DEFINED STRING GOTO MyLabel
REM OR IF "." equals "." GOTO MyLabel
IF "%STRING%." == "." GOTO MyLabel
REM GOTO End of File
GOTO :EOF
:MyLabel
ECHO Welcome!
PAUSE
출력(없음, %1이 공백, 비어 있지 않거나 NULL이 아님):
위의 스크립트1에서 파라미터 없이 실행("Remove Quotes.cmd")
출력(%1이 공백, 비어 있거나 NULL):
Welcome!
Press any key to continue . . .
" " 내에 : " " "IF ( ) ELSE ( )
스테이트먼트는, 「IF」스테이트먼트를 종료할 때까지 사용할 수 없습니다(「Delayed Variable Expansion」가 유효하게 되어 있지 않은 경우, 유효하게 되면, %」기호 대신에 느낌표 「!」를 사용합니다).
예를 들어 다음과 같습니다.
스크립트 2:
입력("Remove Quotes.cmd" "이것은 테스트입니다")
@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET STRING=%0
IF 1==1 (
SET STRING=%1
ECHO String in IF Statement='%STRING%'
ECHO String in IF Statement [delayed expansion]='!STRING!'
)
ECHO String out of IF Statement='%STRING%'
REM Remove Quotes [Only Remove Quotes if NOT Null]
IF DEFINED STRING SET STRING=%STRING:"=%
ECHO String without Quotes=%STRING%
REM IF %1 is NULL GOTO MyLabel
IF NOT DEFINED STRING GOTO MyLabel
REM GOTO End of File
GOTO :EOF
:MyLabel
ECHO Welcome!
ENDLOCAL
PAUSE
출력:
C:\Users\Test>"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd" "This is a Test"
String in IF Statement='"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"'
String in IF Statement [delayed expansion]='"This is a Test"'
String out of IF Statement='"This is a Test"'
String without Quotes=This is a Test
C:\Users\Test>
주의: 문자열 내부에서도 따옴표가 삭제됩니다.
예(스크립트 1 또는 2 사용):C:\Users\Test\Documents\Batch Files>"Remove Quotes.cmd" "이것은 "a" 테스트입니다"
출력(스크립트 2):
String in IF Statement='"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"'
String in IF Statement [delayed expansion]='"This is "a" Test"'
String out of IF Statement='"This is "a" Test"'
String without Quotes=This is a Test
스크립트 2에서 파라미터 없이 ("Remove Quotes.cmd")를 실행합니다.
출력:
Welcome!
Press any key to continue . . .
인터넷에 올라온 답변이 너무 많아서 문제가 많았어요.대부분의 경우 효과가 있지만, 항상 각각의 문제를 해결할 수 있는 코너 케이스가 있습니다.
따옴표가 있으면 효과가 없을 수도 있고 따옴표가 없으면 깨질 수도 있고, var에 공백이 있으면 구문 오류가 발생할 수도 있습니다. 일부는 매개 변수에서만 작동하며(환경 변수와 달리), 다른 기술은 빈 따옴표 집합을 '정의'로 전달할 수 있으며, 더 까다로운 일부 기술은 체인을 허용하지 않습니다.else
나중에.
여기 제가 만족하는 해결책이 있습니다. 만약 도움이 되지 않는 코너 케이스를 발견하면 알려주세요.
:ifSet
if "%~1"=="" (Exit /B 1) else (Exit /B 0)
서브루틴을 스크립트 또는 스크립트에 포함시키는 것.bat
, 가 동작합니다.
따라서 (의사로) 쓰기를 원하는 경우:
if (var)
then something
else somethingElse
다음과 같이 쓸 수 있습니다.
(Call :ifSet %var% && (
Echo something
)) || (
Echo something else
)
모든 테스트에서 효과가 있었습니다.
(Call :ifSet && ECHO y) || ECHO n
(Call :ifSet a && ECHO y) || ECHO n
(Call :ifSet "" && ECHO y) || ECHO n
(Call :ifSet "a" && ECHO y) || ECHO n
(Call :ifSet "a a" && ECHO y) || ECHO n
에코n
,y
,n
,y
,y
기타 예:
- 확인만 하고 싶다
if
?Call :ifSet %var% && Echo set
- 만약 그렇지 않다면?
Call :ifSet %var% || Echo set
- 통과된 인수를 체크합니다.정상적으로 동작합니다.
Call :ifSet %1 && Echo set
- 스크립트/복제 코드를 방해하고 싶지 않았기 때문에, 독자적인 코드로 설정했습니다.
ifSet.bat
? 문제 없습니다.((Call ifSet.bat %var%) && Echo set) || (Echo not set)
빈 문자열 확인에 " 대신 ! 사용
@echo off
SET a=
SET b=Hello
IF !%a%! == !! echo String a is empty
IF !%b%! == !! echo String b is empty
This way looks correct:
if "%~1" == "" if [%1] == [] echo Argument 1 is really empty.
First filter (if "%~1" == "") из safe way to detect argument is empty or "".
Second filter (if [%1] == []) will skip "" argument.
Remember we have two kind of empty arguments : really empty (nothing) and empty quotes "".
We have to detect both.
Next code takes all arguments "as is" in variable args:
:GetArgs
set args=%1
:ParseArgs
shift /1
if "%~1" == "" if [%1] == [] goto :DoneArgs
set args=%args% %1
goto :ParseArgs
:DoneArgs
if not defined args echo No arguments
if defined args echo Aguments are: %args%
This code correctly process "normal" arguments (simple words, "multiword phrases" or "") with balanced quotes.
Quoted arguments can even contain special chars like "a & b".
But it is still can fail with "abnormal" expressions with unbalanced quotes (do not use them).
가장 간단한 솔루션은 두 줄의 코드로 구성됩니다.
SET /A var02 = %var01% / 1
IF %ERRORLEVEL% NEQ 0 (ECHO Variable var01 is NOT EXIST)
입학한 지 한 달도 안 됐어요(8년 전에 물어봤지만)지금쯤이면 배치파일에서 벗어나야 할 텐데.;-) 저는 항상 이 작업을 하고 있었습니다.하지만 궁극적인 목표가 뭔지는 잘 모르겠어요.나처럼 게으른 경우 go.bat은 이와 같은 용도로 사용할 수 있습니다(아래 참조). 단, 1, 입력을 명령어로 직접 사용하는 경우 OP의 명령어가 비활성화될 수 있습니다.
"C:/Users/Me"
는 비활성 명령어입니다(또는 다른 드라이브에 있는 경우 사용).두 부분으로 나눠야 돼요.
C:
cd /Users/Me
그리고 둘째, '정의되지 않음' 또는 '정의되지 않음'은 무엇을 의미합니까?GIGO. 오류를 잡기 위해 기본값을 사용합니다.입력이 잡히지 않으면 도움말(또는 기본 명령)으로 드롭됩니다.따라서 입력은 오류가 아닙니다.입력에 cd를 삽입하여 오류가 있으면 잡을 수 있습니다(Go를 사용하면 DOS에서 "다운로드(paren 하나만)"를 잡을 수 있습니다. (Harsh!)
cd "%1"
if %errorlevel% neq 0 goto :error
셋째, 명령어가 아닌 경로 주변에만 인용이 필요합니다.
"cd C:\Users"
다른 드라이브를 사용하지 않는 한(또는 옛날에는 그랬다) 나빴다.
cd "\Users"
기능하고 있습니다.
cd "\Users\Dr Whos infinite storage space"
는 경로에 공백이 있는 경우 작동합니다.
@REM go.bat
@REM The @ sigh prevents echo on the current command
@REM The echo on/off turns on/off the echo command. Turn on for debugging
@REM You can't see this.
@echo off
if "help" == "%1" goto :help
if "c" == "%1" C:
if "c" == "%1" goto :done
if "d" == "%1" D:
if "d" == "%1" goto :done
if "home"=="%1" %homedrive%
if "home"=="%1" cd %homepath%
if "home"=="%1" if %errorlevel% neq 0 goto :error
if "home"=="%1" goto :done
if "docs" == "%1" goto :docs
@REM goto :help
echo Default command
cd %1
if %errorlevel% neq 0 goto :error
goto :done
:help
echo "Type go and a code for a location/directory
echo For example
echo go D
echo will change disks (D:)
echo go home
echo will change directories to the users home directory (%homepath%)
echo go pictures
echo will change directories to %homepath%\pictures
echo Notes
echo @ sigh prevents echo on the current command
echo The echo on/off turns on/off the echo command. Turn on for debugging
echo Paths (only) with folder names with spaces need to be inclosed in quotes (not the ommand)
goto :done
:docs
echo executing "%homedrive%%homepath%\Documents"
%homedrive%
cd "%homepath%\Documents"\test error\
if %errorlevel% neq 0 goto :error
goto :done
:error
echo Error: Input (%1 %2 %3 %4 %5 %6 %7 %8 %9) or command is invalid
echo go help for help
goto :done
:done
언급URL : https://stackoverflow.com/questions/2541767/what-is-the-proper-way-to-test-if-a-parameter-is-empty-in-a-batch-file
'programing' 카테고리의 다른 글
Swift: 어레이를 참조로 전달하시겠습니까? (0) | 2023.04.19 |
---|---|
Mac OS 10.10+에서 GNU sed를 사용하는 방법, 'brew install --default-names'는 더 이상 지원되지 않습니다. (0) | 2023.04.19 |
SQL Server의 모든 데이터베이스 파일에 대한 정보 나열 (0) | 2023.04.19 |
Ruby에서 문자열을 소문자로 변환하는 방법 (0) | 2023.04.19 |
현재 체크아웃된 Git 브랜치를 프로그래밍 방식으로 결정하는 방법 (0) | 2023.04.19 |