testingbatch file中variables是否为空的正确方法是什么?

我需要testing一个variables是否设置。 我已经尝试了几种技术,但是当%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语法types。 所以,我没有办法做到这一点。

 IF [NOT] ERRORLEVEL number command IF [NOT] string1==string2 command IF [NOT] EXIST filename command 

使用方括号而不是引号:

 IF [%1] == [] GOTO MyLabel 

圆括号不安全 :只使用方括号。

您可以使用:

 IF "%~1" == "" GOTO MyLabel 

剥去外面的一套报价。 一般来说,这是比使用方括号更可靠的方法,因为即使variables中有空格,它也可以工作。

最好的半解决scheme之一是将%1复制到一个variables中,然后使用delayedExp作为延迟扩展。 对任何内容总是安全的。

 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 "&"^& 

如果你想99%的防弹,你可以阅读如何接收甚至最奇怪的命令行参数?

从IF /?:

如果启用命令扩展如果更改如下:

 IF [/I] string1 compare-op string2 command IF CMDEXTVERSION number command IF DEFINED variable command 

……

DEFINED条件与EXISTS类似,只是它需要一个环境variables名称,如果定义了环境variables,则返回true。

使用“IF DEFINEDvariables命令”在batch file中testingvariables。

但如果你想testing批处理参数,请尝试下面的代码,以避免棘手的input(如“1 2”或ab ^> cd)

 set tmp="%1" if "%tmp:"=.%"==".." ( echo empty ) else ( echo not empty ) 

空string是一对double-quotes / "" ,我们可以只testing一下长度:

 set ARG=%1 if not defined ARG goto nomore set CHAR=%ARG:~2,1% if defined CHAR goto goon 

然后用double-quotestesting2个字符:

 if ^%ARG:~1,1% == ^" if ^%ARG:~0,1% == ^" goto blank ::else goto goon 

这是一个可以玩的批处理脚本。 我认为它正确地捕捉到空的string。

这只是一个例子,你只需要根据你的脚本自定义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 /ai=%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 

这个折磨testing结果:

 .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" " "< "">" (")(") "" :: ""-" " "( )"">\>" "" 

我通常使用这个:

 IF "%1."=="." GOTO MyLabel 

如果%1为空,则IF将比较“。” 至 ”。” 这将评估为真。

脚本1:

input(“删除Quotes.cmd”“这是一个testing”)

 @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):


运行(“删除Quotes.cmd”)没有任何参数与上述脚本1

输出(%1为空,空或NULL):

 Welcome! Press any key to continue . . . 

注意:如果你在IF ( ) ELSE ( )语句中设置了一个variables,直到它退出“IF”语句之后,它才能被DEFINED使用(除非“Delayed Variable Expansion”被启用;一旦被激活使用感叹号“ !“代替%”%“符号}。

例如:

脚本2:

input(“删除Quotes.cmd”“这是一个testing”)

 @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> 

注意:它也会从string中删除引号。

例如(使用脚本1或2):C:\ Users \ Test \ Documents \ Batch Files>“Remove Quotes.cmd”“This is”a“Test”

输出(脚本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 

执行(“删除Quotes.cmd”)脚本2中没有任何参数:

输出:

 Welcome! Press any key to continue . . . 

我根据这里的答案创build了这个小批处理脚本,因为有许多有效的脚本。 随意添加到这个,只要你遵循相同的格式:

 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 

总结一下:

 set str=%~1 if not defined str ( echo Empty string ) 

如果%1为“”或“或空”,则此代码将输出“空string”,将其添加到当前接受的错误答案中。

网上有很多答案,我有很多的问题。 大部分工作对大多数事情来说,但总是有一个angular落的情况下打破每一个。
也许这不工作,如果它有引号,也许它打破了,如果没有引号,语法错误,如果var有一个空间,有些只会在参数(而不是环境variables)工作,其他技术允许一个空一套引号作为“定义”传递,一些棘手的将不会让你连锁。

这是我很满意的解决scheme,请让我知道,如果你发现一个angular落的情况下,它不会工作。

 :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 ) 

它适用于我所有的testing:

 (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 "aa" && ECHO y) || ECHO n 

回声nynyy


更多例子:

  • 只想检查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) ((Call ifSet.bat %var%) && Echo set) || (Echo not set)

使用! 而不是“空string检查

 @echo off SET a= SET b=Hello IF !%a%! == !! echo String a is empty IF !%b%! == !! echo String b is empty 

您可以使用

 if defined (variable) echo That's defined! if not defined (variable) echo Nope. Undefined.