如何检查“.bat”文件中的命令行参数?

我的操作系统是Windows Vista。 我需要一个“.bat”文件,我需要检查用户是否input任何命令行参数。 如果那么如果参数等于-b那么我会做一些事情,否则我会标记“无效的input”。 如果用户没有input任何命令行参数,那么我会做一些事情。 我创build了以下.bat文件。 它适用于-b和不等于-b情况,但在用户不传递任何命令行参数时失败。

我总是得到错误:

 GOTO was unexpected at this time. 

谁能告诉我我在这里做错了什么?


 ECHO OFF CLS ECHO. IF [%1]==[/?] GOTO BLANK IF %1=="-b" GOTO SPECIFIC IF NOT %1=="-b" GOTO UNKNOWN :SPECIFIC ECHO SPECIFIC GOTO DONE :BLANK ECHO No Parameter GOTO DONE :UNKNOWN ECHO Unknown Option GOTO DONE :DONE ECHO Done! 

你需要检查参数是否为空: if "%~1"=="" goto blank

一旦你这样做,然后做一个if / else开关-b: if "%~1"=="-b" (goto specific) else goto unknown

用引号括起来的参数使检查诸如空白/空/缺less参数更容易。 “〜”确保双引号在命令行参数中被删除。

看看http://ss64.com/nt/if.html的答案;; 该命令是IF [%1]==[] GOTO NO_ARGUMENT或类似的。

除了我订阅的其他答案之外,您可以考虑使用IF命令的/I开关。

… / I开关,如果指定,说做不区分大小写的string比较。

如果你想给你的用户指定参数不区分大小写的灵活性可能会有所帮助。

 IF /I "%1"=="-b" GOTO SPECIFIC 

你正在比较string。 如果省略参数, %1将展开为空,因此命令将变成IF =="-b" GOTO SPECIFIC例如IF =="-b" GOTO SPECIFIC (这是语法错误)。 用引号(或方括号)包装你的string。

 REM this is ok IF [%1]==[/?] GOTO BLANK REM I'd recommend using quotes exclusively IF "%1"=="-b" GOTO SPECIFIC IF NOT "%1"=="-b" GOTO UNKNOWN 

简短的答案 – 使用方括号:

 if [%1]==[] goto :blank 

或(当你需要处理引用的参数,请参阅下面的编辑):

 if [%~1]==[] goto :blank 

为什么? 你可能会问。 那么,就像Jeremiah Willcock所说: http : //ss64.com/nt/if.html – 他们使用它! 好的,但是报价有什么问题?

再次,简短的回答:他们是“神奇的” – 有时双(双)报价转换为单(双)报价。 他们需要匹配,一开始。

考虑一下这个小脚本:

 @rem argq.bat @echo off :loop if "%1"=="" goto :done echo %1 shift goto :loop :done echo Done. 

我们来testing一下:

 C:\> argq bla bla bla bla Done. 

似乎工作。 但现在,让我们切换到二档:

 C:\> argq "bla bla" bla""=="" was unexpected at this time. 

繁荣这并没有评估为真,也没有评估为假。 脚本DIED。 如果你应该closures反应堆的某个地方,好运气。 你现在会像Harry Daghlian一样死去。

你可能会认为 – 好的,参数不能包含引号。 如果他们这样做,这发生。 错误这里有一些安慰:

 C:\> argq ""bla bla"" ""bla bla"" Done. 

哦耶。 不要担心 – 有时候这样做起作用。

让我们尝试另一个脚本:

 @rem args.bat @echo off :loop if [%1]==[] goto :done echo %1 shift goto :loop :done echo Done. 

你可以testing一下自己,对于上面的情况,它可以正常工作。 这是合乎逻辑的 – 引号与括号无关,所以这里没有魔法。 但是如何用括号来激发你的想法呢?

 D:\>args ]bla bla[ ]bla bla[ Done. D:\>args [bla bla] [bla bla] Done. 

那里没有运气。 括号不能阻塞cmd.exe的parsing器。

让我们回到邪恶的引言片刻。 问题在那里,当争论结束了引用:

 D:\>argq "bla1 bla2" bla2""=="" was unexpected at this time. 

如果我只是通过:

 D:\>argq bla2" The syntax of the command is incorrect. 

该脚本将不会运行。 相同的args.bat

 D:\>args bla2" The syntax of the command is incorrect. 

但是,当"字符”的数目匹配(即 – 是偶数)时,我会得到什么结果,在这种情况下:

 D:\>args bla2" "bla3 bla2" "bla3 Done. 

很好 – 我希望你学到了一些关于.bat文件如何拆分它们的命令行参数(提示:*这不完全像在bash中)。 上面的参数包含一个空格。 但报价不会自动剥离。

和argq? 它如何反应? 可以预见的是:

 D:\>argq bla2" "bla3 "bla3"=="" was unexpected at this time. 

所以 – 想想之前你说:“知道什么?只要用引号[因为,对我来说,这看起来更好]”。

编辑

最近有关于这个答案的评论 – 好吧,sqare括号“不能处理”通过引用的论据,并把它们对待,就像他们没有引用。

语法:

 if "%~1"=="" (...) 

如果第一个和最后一个字符是双引号,那么不是新引用的双引号的优点,而是显示从引数variables中剥离引号的整齐特征。

这个“技术”和方括号一样好用:

 if [%~1]==[] (...) 

指出这一点是非常有用的,所以我也提出了新的答案。

最后,双引号的粉丝,你的书中是否存在""这个forms的争论,还是空白? 只是要求;)

其实所有其他答案都有缺陷。 最可靠的方法是:

 IF "%~1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN) 

详细说明:

使用"%1"=="-b"如果用空格和引号传递参数将会崩溃。 这是最不可靠的方法。

 IF "%1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN) C:\> run.bat "ab" b""=="-b" was unexpected at this time. 

使用[%1]==[-b]更好,因为它不会使用空格和引号崩溃,但如果参数被引号包围,则不会匹配。

 IF [%1]==[-b] (GOTO SPECIFIC) ELSE (GOTO UNKNOWN) C:\> run.bat "-b" (does not match, and jumps to UNKNOWN instead of SPECIFIC) 

使用"%~1"=="-b"是最可靠的。 如果存在, %~1将剥离周围的报价。 所以它适用于和不用引号,也没有参数。

 IF "%~1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN) C:\> run.bat C:\> run.bat -b C:\> run.bat "-b" C:\> run.bat "ab" (all of the above tests work correctly)