我需要测试是否设置了一个变量。我尝试了几种技术,但每当%1被引号包围时,它们似乎都失败了,例如%1是“c:\一些带空格的路径”。

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,我更新了接受的答案,从使用括号到使用波浪号。每个人都说波浪更好,因为它更安全。我有点撕裂,因为波浪线看起来更复杂,不太清楚它的目的是什么,但尽管如此,我改变了它。


当前回答

使用!而不是“空字符串检查”

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

其他回答

脚本1:

输入(“删除引号。”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):


使用上面的脚本运行("Remove Quotes.cmd"),不带任何参数

输出(%1为空白、空或NULL):

Welcome!

Press any key to continue . . .

注意:如果你在If () ELSE()语句中设置了一个变量,它将在退出If语句后才对DEFINED可用(除非“延迟变量扩展”被启用;一旦启用,请使用感叹号“!”来代替百分比“%”符号}。

例如:

脚本2:

输入(“删除引号。”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 \批处理文件>"删除引号。cmd"这是"一个"测试"

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

空字符串是一对双引号/"",我们可以直接测试长度:

set ARG=%1
if not defined ARG goto nomore

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

然后用双引号测试它的2个字符:

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

你可以使用

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

从IF /?:

如果命令扩展是启用If 变更如下: IF [/I] string1 compare-op string2命令 IF CMDEXTVERSION编号命令 IF定义变量命令 ...... DEFINED条件刚好 像EXISTS一样,除了它需要一个 环境变量名称和返回值 如果环境变量为,则为 定义的。