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

时间:2022-10-10 15:03:32

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!

6 个解决方案

#1


101  

You need to check for the parameter being blank: if "%~1"=="" goto blank

您需要检查参数是否为空:如果“%~1”==“”转到空白

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”(转到特定)否则转到未知

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.

使用引号包围参数可以更轻松地检查空白/空/缺少参数等内容。 “〜”确保双引号在命令行参数中被删除。

#2


23  

Look at http://ss64.com/nt/if.html for an answer; the command is IF [%1]==[] GOTO NO_ARGUMENT or similar.

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

#3


9  

The short answer - use square brackets:

简答 - 使用方括号:

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

or (when you need to handle quoted args, see the Edit below):

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

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.

Boom This 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.

繁荣这没有评价为真,它也没有评价为假。脚本DIED。如果你应该在某个地方关闭反应堆,那么运气不错。你现在会像Harry Daghlian一样死去。

You may think - OK, the arguments can't contain quotes. If they do, this happens. Wrong Here's some consolation:

您可能认为 - 好吧,参数不能包含引号。如果他们这样做,就会发生错了这里有一些安慰:

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

Oh yeah. Don't worry - sometimes this will work.

哦耶。别担心 - 有时这会奏效。

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?

您可以测试自己,它适用于上述情况。这是合乎逻辑的 - 引号与括号无关,因此这里没有任何魔力。但是如何用支架来加工args呢?

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.

NICE - 我希望你学到了一些关于.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.

最近,有关于这个答案的评论 - 好吧,sqare括号“无法处理”传递引用的参数并将它们视为没有引用它们。

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' ;)

最后,双引号粉丝,你的书中是否存在“”形式的论点,或者它是空白的?请问';)

#4


7  

In addition to the other answers, which I subscribe, you may consider using the /I switch of the IF command.

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

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

#5


5  

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

#6


3  

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将剥离周围的引号。因此它可以使用和不使用引号,也可以不使用args。

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)

#1


101  

You need to check for the parameter being blank: if "%~1"=="" goto blank

您需要检查参数是否为空:如果“%~1”==“”转到空白

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”(转到特定)否则转到未知

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.

使用引号包围参数可以更轻松地检查空白/空/缺少参数等内容。 “〜”确保双引号在命令行参数中被删除。

#2


23  

Look at http://ss64.com/nt/if.html for an answer; the command is IF [%1]==[] GOTO NO_ARGUMENT or similar.

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

#3


9  

The short answer - use square brackets:

简答 - 使用方括号:

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

or (when you need to handle quoted args, see the Edit below):

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

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.

Boom This 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.

繁荣这没有评价为真,它也没有评价为假。脚本DIED。如果你应该在某个地方关闭反应堆,那么运气不错。你现在会像Harry Daghlian一样死去。

You may think - OK, the arguments can't contain quotes. If they do, this happens. Wrong Here's some consolation:

您可能认为 - 好吧,参数不能包含引号。如果他们这样做,就会发生错了这里有一些安慰:

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

Oh yeah. Don't worry - sometimes this will work.

哦耶。别担心 - 有时这会奏效。

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?

您可以测试自己,它适用于上述情况。这是合乎逻辑的 - 引号与括号无关,因此这里没有任何魔力。但是如何用支架来加工args呢?

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.

NICE - 我希望你学到了一些关于.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.

最近,有关于这个答案的评论 - 好吧,sqare括号“无法处理”传递引用的参数并将它们视为没有引用它们。

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' ;)

最后,双引号粉丝,你的书中是否存在“”形式的论点,或者它是空白的?请问';)

#4


7  

In addition to the other answers, which I subscribe, you may consider using the /I switch of the IF command.

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

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

#5


5  

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

#6


3  

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将剥离周围的引号。因此它可以使用和不使用引号,也可以不使用args。

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)