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

ippsafx7  于 2023-02-13  发布在  Windows
关注(0)|答案(8)|浏览(608)

我的操作系统是Windows Vista。我需要有一个". bat"文件,我需要检查用户是否输入任何命令行参数或没有。如果这样做,那么如果参数等于-b,那么我会做一些事情,否则我会标记"无效输入"。如果用户没有输入任何命令行参数,那么我会做一些事情。我创建了以下. 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!
j0pj023g

j0pj023g1#

您需要检查参数是否为空:if "%~1"=="" goto blank
一旦你完成了这个,然后执行if/else命令打开-B:if "%~1"=="-b" (goto specific) else goto unknown
用引号将参数括起来可以更容易地检查空白/空/缺少参数等情况。“~”确保在命令行参数中使用双引号时将其去掉。

c7rzv4ha

c7rzv4ha2#

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

ljsrvy3e

ljsrvy3e3#

简短答案-使用方括号:

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

或者(当你需要处理带引号的参数时,请看下面的编辑):

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

为什么?你可能会问。嗯,正如耶利米·威尔科克提到的:http://ss64.com/nt/if.html-他们用那个!好吧,但是引号有什么问题?
简单回答:它们是"神奇的"-有时双(双)引号会转换成单(双)引号。而且它们需要匹配,首先。
请看下面这个小脚本:

@rem argq.bat
@echo off

:loop 
if "%1"=="" goto :done
echo %1
shift
goto :loop

:done
echo Done.

我们来测试一下:

C:\> argq bla bla
bla
bla
Done.

好像有用。但现在,让我们换到第二档:

C:\> argq "bla bla"
bla""=="" was unexpected at this time.
    • 嘣**这个结果不是真的,也不是假的。脚本死了。如果你应该在某个地方关掉React堆,那么--真倒霉。你现在会像哈里·达格利安一样死。

你可能会想--好吧,参数不能包含引号,如果包含引号,就会发生这种情况。错了这里有一些安慰:

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.

你可以自己测试一下,看看它在上述情况下是否正常工作。这是合乎逻辑的--引号和括号没有关系,所以这里没有魔法。但是用括号给参数加香料怎么样?

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

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

这可不走运,括号根本无法阻塞cmd.exe的解析器。
让我们回到那些邪恶的引语,问题就在那里,当争论以一句引语结束时:

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.
    • NICE**-我希望您了解了.bat文件如何拆分其命令行参数(提示:* 这和bash不完全一样)上面的参数包含了一个空格,但是引号不会被自动去掉。

那么argq呢?它对此有何React?可以预见:

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

所以-在你说之前想一想:知道吗?就用引号吧。(因为,对我来说,这看起来更好)。

    • 编辑**

最近,有一些关于这个答案的评论--嗯,方括号"不能处理"传递带引号的参数,并把它们当作没有带引号的参数来对待。
语法:

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

并不是新发现的双引号的优点,而是一个简洁的特性,即如果第一个和最后一个字符是双引号,则可以从参数变量中剥离引号。
这种"技术"在方括号中同样适用:

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

指出这一点是很有用的,所以我也赞成新的答案。
最后,双引号的粉丝们,你们的书中有""形式的论点吗,还是空白的?只是问问;)

9lowa7mx

9lowa7mx4#

除了我所订阅的其他答案之外,您还可以考虑使用IF命令的/I开关。
...如果指定了/I开关,则表示执行不区分大小写的字符串比较。
如果你想给予你的用户在指定参数时不区分大小写,这可能会有所帮助。

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

0yg35tkg5#

您正在比较字符串。如果省略参数,%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
svujldwt

svujldwt6#

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

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

详细说明:

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

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

C:\> run.bat "a b"

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 "a b"

(all of the above tests work correctly)
8ljdwjyq

8ljdwjyq7#

我最近一直在努力在一个批处理文件中实现复杂的参数开关,所以这里是我的研究结果。没有一个提供的答案是完全安全的,例如:
"%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="-?"

如果参数的引号中有空格,则方括号[%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.

所提出的最安全的解决方案"%~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.

确保涵盖上述所有场景的唯一方法是使用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"
70gysomp

70gysomp8#

这个问题已经有了一些很好的答案,但是所有的答案似乎都坚持使用goto
如果您不想在2023年Windows 10中使用goto,这会稍微复杂一些,您可以在if语句后简单地使用括号()
因此,您完全可以创建如下所示的批处理文件:

@echo off

if "%~1"=="full" (
echo hello
echo hello again
)

echo hello always

如果使用以下命令行执行此操作:if_argument_test.bat full您将看到:

hello
hello again
hello always

如果不使用full参数执行该命令,您将看到以下内容:

hello always

没有goto的批处理代码更干净。

相关问题