windows 如何检查“.bat”文件中的命令行参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4953170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check command line parameter in ".bat" file?
提问by javauser71
My OS is Windows Vista. I need to have a ".bat" file where I need to check if user enters any command-line parameter or not. If does then if the parameter equals to -b
then I will do something otherwise I will flag "Invalid input". If user does not enter any command-line parameter then I will do something. I have created following .bat file. It works for -b
and not-equal to -b
cases - but it fails when user does not pass any command-line parameter.
我的操作系统是 Windows Vista。我需要有一个“.bat”文件,我需要在其中检查用户是否输入了任何命令行参数。如果是,那么如果参数等于-b
那么我会做一些事情,否则我会标记“无效输入”。如果用户没有输入任何命令行参数,那么我会做一些事情。我创建了以下 .bat 文件。它适用于-b
并且不等于-b
情况 - 但是当用户不传递任何命令行参数时它会失败。
I always get error:
我总是收到错误:
GOTO was unexpected at this time.
Can anyone tell me what am I doing wrong here?
谁能告诉我我在这里做错了什么?
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!
回答by afrazier
You need to check for the parameter being blank: if "%~1"=="" goto blank
您需要检查参数是否为空: if "%~1"=="" goto blank
Once you've done that, then do an if/else switch on -b: if "%~1"=="-b" (goto specific) else goto unknown
完成后,然后在 -b 上执行 if/else 开关: if "%~1"=="-b" (goto specific) else goto unknown
Surrounding the parameters with quotes makes checking for things like blank/empty/missing parameters easier. "~" ensures double quotes are stripped if they were on the command line argument.
用引号将参数括起来可以更轻松地检查诸如空白/空/缺失参数之类的内容。"~" 确保双引号在命令行参数中被删除。
回答by Jeremiah Willcock
Look at http://ss64.com/nt/if.htmlfor an answer; the command is IF [%1]==[] GOTO NO_ARGUMENT
or similar.
查看http://ss64.com/nt/if.html以获得答案;命令是IF [%1]==[] GOTO NO_ARGUMENT
或类似的。
回答by Tomasz Gandor
The short answer - use square brackets:
简短的回答 - 使用方括号:
if [%1]==[] goto :blank
or (when you need to handle quoted args, see the Edit below):
或(当您需要处理引用的参数时,请参阅下面的编辑):
if [%~1]==[] goto :blank
Why? you might ask. Well, just as Jeremiah Willcock mentioned: http://ss64.com/nt/if.html- they use that! OK, but what's wrong with the quotes?
为什么?你可能会问。好吧,正如 Jeremiah Willcock 提到的:http: //ss64.com/nt/if.html- 他们使用它!好的,但是引号有什么问题?
Again, short answer: they are "magical" - sometimes double (double) quotes get converted to a single (double) quote. And they need to match, for a start.
再次,简短的回答:它们是“神奇的” - 有时双(双)引号会转换为单(双)引号。首先,他们需要匹配。
Consider this little script:
考虑这个小脚本:
@rem argq.bat
@echo off
:loop
if "%1"=="" goto :done
echo %1
shift
goto :loop
:done
echo Done.
Let's test it:
让我们测试一下:
C:\> argq bla bla
bla
bla
Done.
Seems to work. But now, lets switch to second gear:
似乎工作。但是现在,让我们切换到二档:
C:\> argq "bla bla"
bla""=="" was unexpected at this time.
BoomThis didn't evaluate to true, neither did it evaluate to false. The script DIED. If you were supposed to turn off the reactor somewhere down the line, well - tough luck. You now will die like Harry Daghlian.
BoomThis 没有评估为真,也没有评估为假。剧本死了。如果你应该在生产线上的某个地方关闭反应堆,那么 - 运气不好。你现在会像哈里·达格利安一样死去。
You may think - OK, the arguments can't contain quotes. If they do, this happens. WrongHere's some consolation:
您可能会想 - 好吧,参数不能包含引号。如果他们这样做,就会发生这种情况。错误这是一些安慰:
C:\> argq ""bla bla""
""bla
bla""
Done.
Oh yeah. Don't worry - sometimesthis willwork.
哦耶。别担心 -有时这会奏效。
Let's try another script:
让我们尝试另一个脚本:
@rem args.bat
@echo off
:loop
if [%1]==[] goto :done
echo %1
shift
goto :loop
:done
echo Done.
You can test yourself, that it works OK for the above cases. This is logical - quotes have nothing to do with brackets, so there's no magic here. But what about spicing the args up with brackets?
您可以自己测试一下,在上述情况下它可以正常工作。这是合乎逻辑的 - 引号与括号无关,所以这里没有魔法。但是如何用括号为参数增加趣味呢?
D:\>args ]bla bla[
]bla
bla[
Done.
D:\>args [bla bla]
[bla
bla]
Done.
No luck there. The brackets just can't choke cmd.exe
's parser.
没有运气。括号不能阻塞cmd.exe
的解析器。
Let's go back to the evil quotes for a moment. The problem was there, when the argument ended with a quote:
让我们暂时回到邪恶的报价。问题就在那里,当争论以引号结束时:
D:\>argq "bla1 bla2"
bla2""=="" was unexpected at this time.
What if I pass just:
如果我只是通过了怎么办:
D:\>argq bla2"
The syntax of the command is incorrect.
The script won't run at all. Same for args.bat
:
脚本根本不会运行。同样适用于args.bat
:
D:\>args bla2"
The syntax of the command is incorrect.
But what do I get, when the number of "
-characters "matches" (i.e. - is even), in such a case:
但是"
,在这种情况下,当-characters的数量“匹配”(即 - 是偶数)时,我会得到什么:
D:\>args bla2" "bla3
bla2" "bla3
Done.
NICE- I hope you learned something about how .bat
files split their command line arguments (HINT: *It's not exactly like in bash). The above argument contains a space. But the quotes are not stripped automatically.
很好- 我希望您了解了.bat
文件如何拆分它们的命令行参数(提示:*这与 bash 中的不完全一样)。上面的参数包含一个空格。但引号不会自动剥离。
And argq? How does it react to that? Predictably:
和 argq?它对此有何反应?可以预见:
D:\>argq bla2" "bla3
"bla3"=="" was unexpected at this time.
So - think before you say: "Know what? Just use quotes. [Because, to me, this looks nicer]".
所以 - 在你说之前想一想:“知道什么?只需使用引号。[因为,对我来说,这看起来更好]”。
Edit
编辑
Recently, there were comments about this answer - well, sqare brackets "can't handle" passing quoted arguments and treating them just as if they weren't quoted.
最近,有关于这个答案的评论 - 好吧,方括号“无法处理”传递带引号的参数并将它们视为没有被引用。
The syntax:
语法:
if "%~1"=="" (...)
Is not some newly found virtue of the double quotes, but a display of a neat feature of stripping quotes from the argument variable, if the first and last character is a double quote.
不是双引号的一些新发现的优点,而是如果第一个和最后一个字符是双引号,则显示从参数变量中剥离引号的简洁功能。
This "technology" works just as well with square brackets:
这种“技术”同样适用于方括号:
if [%~1]==[] (...)
It was a useful thing to point this out, so I also upvote the new answer.
指出这一点很有用,所以我也赞成新的答案。
Finally, double quote fans, does an argument of the form ""
exist in your book, or is it blank? Just askin' ;)
最后,双引号爱好者,""
你的书中是否存在这种形式的论证,还是空白?只是问问';)
回答by PA.
In addition to the other answers, which I subscribe, you may consider using the /I
switch of the IF
command.
除了我订阅的其他答案之外,您还可以考虑使用命令的/I
开关IF
。
... the /I switch, if specified, says to do case insensitive string compares.
... /I 开关(如果指定)表示进行不区分大小写的字符串比较。
it may be of help if you want to give case insensitive flexibility to your users to specify the parameters.
如果您想为用户提供不区分大小写的灵活性来指定参数,这可能会有所帮助。
IF /I "%1"=="-b" GOTO SPECIFIC
回答by Jeff Mercado
You are comparing strings. If an arguments are omitted, %1
expands to a blank so the commands become IF =="-b" GOTO SPECIFIC
for example (which is a syntax error). Wrap your strings in quotes (or square brackets).
您正在比较字符串。如果省略参数,则%1
扩展为空白,因此命令变为IF =="-b" GOTO SPECIFIC
例如(这是语法错误)。将您的字符串用引号(或方括号)括起来。
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
回答by wisbucky
Actually, all the other answers have flaws. The most reliable way is:
实际上,所有其他答案都有缺陷。最可靠的方法是:
IF "%~1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)
Detailed Explanation:
详细说明:
Using "%1"=="-b"
will flat out crash if passing argument with spaces and quotes. This is the least reliable method.
"%1"=="-b"
如果使用空格和引号传递参数,使用将导致崩溃。这是最不可靠的方法。
IF "%1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)
C:\> run.bat "a b"
b""=="-b" was unexpected at this time.
Using [%1]==[-b]
is better because it will not crash with spaces and quotes, but it will not match if the argument is surrounded by quotes.
使用[%1]==[-b]
更好,因为它不会因空格和引号而崩溃,但如果参数被引号包围,它将不匹配。
IF [%1]==[-b] (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)
C:\> run.bat "-b"
(does not match, and jumps to UNKNOWN instead of SPECIFIC)
Using "%~1"=="-b"
is the most reliable. %~1
will strip off surrounding quotes if they exist. So it works with and without quotes, and also with no args.
使用"%~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 "a b"
(all of the above tests work correctly)
回答by D.Barev
I've been struggling recently with the implementation of complex parameter switches in a batch file so here is the result of my research. None of the provided answers are fully safe, examples:
我最近一直在努力在批处理文件中实现复杂的参数切换,所以这是我的研究结果。提供的答案都不是完全安全的,例如:
"%1"=="-?"
will not match if the parameter is enclosed in quotes (needed for file names etc.) or will crash if the parameter is in quotes and has spaces (again often seen in file names)
"%1"=="-?"
如果参数用引号括起来(文件名等需要)将不匹配,或者如果参数用引号引起来并且有空格(同样经常出现在文件名中)则会崩溃
@ECHO OFF
SETLOCAL
echo.
echo starting parameter test...
echo.
rem echo First parameter is %1
if "%1"=="-?" (echo Condition is true, param=%1) else (echo Condition is false, param=%1)
C:\>test.bat -?
starting parameter test...
Condition is true, param=-?
C:\>test.bat "-?"
starting parameter test...
Condition is false, param="-?"
Any combination with square brackets [%1]==[-?]
or [%~1]==[-?]
will fail in case the parameter has spaces within quotes:
与方括号的任何组合[%1]==[-?]
或[%~1]==[-?]
将失败,如果参数在引号内有空格:
@ECHO OFF
SETLOCAL
echo.
echo starting parameter test...
echo.
echo First parameter is %1
if [%~1]==[-?] (echo Condition is true, param=%1) else (echo Condition is false, param=%1)
C:\>test.bat "long file name"
starting parameter test...
First parameter is "long file name"
file was unexpected at this time.
The proposed safest solution "%~1"=="-?"
will crash with a complex parameter that includes text outside the quotes and text with spaces within the quotes:
建议的最安全解决方案"%~1"=="-?"
将因包含引号外的文本和引号内带有空格的文本的复杂参数而崩溃:
@ECHO OFF
SETLOCAL
echo.
echo starting parameter test...
echo.
echo First parameter is %1
if "%~1"=="-?" (echo Condition is true, param=%1) else (echo Condition is false, param=%1)
C:\>test.bat -source:"long file name"
starting parameter test...
First parameter is -source:"long file name"
file was unexpected at this time.
The only way to ensure all above scenarios are covered is to use EnableDelayedExpansionand to pass the parameters by reference (not by value) using variables. Then even the most complex scenario will work fine:
确保涵盖所有上述场景的唯一方法是使用EnableDelayedExpansion并使用变量通过引用(而不是通过值)传递参数。那么即使是最复杂的场景也能正常工作:
@ECHO OFF
SETLOCAL EnableDelayedExpansion
echo.
echo starting parameter test...
echo.
echo First parameter is %1
:: we assign the parameter to a variable to pass by reference with delayed expansion
set "var1=%~1"
echo var1 is !var1!
:: we assign the value to compare with to a second variable to pass by reference with delayed expansion
set "var2=-source:"c:\app images"\image.png"
echo var2 is !var2!
if "!var1!"=="!var2!" (echo Condition is true, param=!var1!) else (echo Condition is false, param=!var1!)
C:\>test.bat -source:"c:\app images"\image.png
starting parameter test...
First parameter is -source:"c:\app images"\image.png
var1 is -source:"c:\app images"\image.png
var2 is -source:"c:\app images"\image.png
Condition is true, param=-source:"c:\app images"\image.png
C:\>test.bat -source:"c:\app images"\image1.png
starting parameter test...
First parameter is -source:"c:\app images"\image1.png
var1 is -source:"c:\app images"\image1.png
var2 is -source:"c:\app images"\image.png
Condition is false, param=-source:"c:\app images"\image1.png
C:\>test.bat -source:"c:\app images\image.png"
starting parameter test...
First parameter is -source:"c:\app images\image.png"
var1 is -source:"c:\app images\image.png"
var2 is -source:"c:\app images"\image.png
Condition is false, param=-source:"c:\app images\image.png"
回答by Charles
Windows batch has the DEFINED keyword for doing this.
Windows 批处理具有用于执行此操作的 DEFINED 关键字。
IF DEFINED %~1 foo
IF NOT DEFINED %~1 bar