我需要测试是否设置了一个变量。我尝试了几种技术,但每当%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,我更新了接受的答案,从使用括号到使用波浪号。每个人都说波浪更好,因为它更安全。我有点撕裂,因为波浪线看起来更复杂,不太清楚它的目的是什么,但尽管如此,我改变了它。


当前回答

脚本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 . . .

其他回答

我在不到一个月的时间里就被录取了(尽管这是8年前的要求)……我希望他/她现在已经超越批处理文件了。: -) 我以前经常这么做。但我不确定最终目标是什么。如果他/她像我一样懒,我的go.bat就能解决这些问题。(见下文) 但是,1,如果您直接将输入作为命令使用,则OP中的命令可能无效。也就是说,

"C:/Users/Me"

是无效命令(如果您在不同的驱动器上,则过去是无效命令)。你得把它分成两部分。

C:
cd /Users/Me

第二,'defined'和'undefined'是什么意思?GIGO。我使用默认值来捕捉错误。如果输入没有被捕获,它将被删除以帮助(或默认命令)。所以,没有输入不是错误。您可以尝试cd到输入并捕捉错误(如果有的话)。(好的,使用go "downloads(只有一个括号)被DOS捕获。(严厉的!)

cd "%1"
if %errorlevel% neq 0 goto :error

并且,3,引号只需要围绕路径,而不是命令。也就是说,

"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

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

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

我测试下面的代码,它是好的。

@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将比较"."和".",结果为真。

不幸的是,我没有足够的声誉来评论或投票目前的答案,我不得不自己写。

最初OP的问题说的是“变量”而不是“参数”,这让人非常困惑,特别是因为这是谷歌中搜索如何测试空白变量的头号链接。自从我最初的答案以来,Stephan编辑了原始问题,以使用正确的术语,但我没有删除我的答案,而是决定留下它来帮助澄清任何困惑,特别是在谷歌仍然派人来这里寻找变量的情况下:

%1不是变量!它是一个命令行参数。

非常重要的区别。后面带数字的单个百分号表示命令行参数,而不是变量。

使用set命令设置变量,并使用2%符号(一个在前面,一个在后面)回收变量。例如%myvar%

要测试空变量,您可以使用“if not defined”语法(显式变量命令不需要任何百分号),例如:

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的答案。)