启动/调用批处理文件时,如何检查是否定义了参数?


96

我正在尝试在批处理文件中使用以下验证逻辑,但是即使未向批处理文件提供任何参数,“ usage”块也永远不会执行。

if ("%1"=="") goto usage

@echo This should not execute

@echo Done.
goto :eof

:usage
@echo Usage: %0 <EnvironmentName>
exit 1

我究竟做错了什么?


Answers:


146

检查是否已设置命令行参数可以是[%1]==[],但是正如Dave Costa 指出的那样"%1"==""也可以。

我还修复了用法回显中的语法错误,以避开大于和小于符号。另外,exit需要的/B论点CMD.exe将会退出。

@echo off

if [%1]==[] goto usage
@echo This should not execute
@echo Done.
goto :eof
:usage
@echo Usage: %0 ^<EnvironmentName^>
exit /B 1

18
[%1] == []优于“%1” ==“”,因为它可以正确处理%1本身包含双引号的情况。“%1” ==“”将错误,并显示一条“此时异常”消息。
tekumara '02

2
请注意,如果您不是使用命令行参数而是set变量(我不知道正确的批处理术语),则可能要使用,"%myvar%"==""因为如果其中myvar有空格且未加引号,则此时将得到“意外的“ 信息。
2012年

1
@Pat SET变量可以用IF NOT DEFINED VarNameblock 检查。还要为tukushan +1(因为未在比较中使用引号)。只是不要这样做。决不。
Fr0sT

10
"%~1"==""还将努力并采取了这样的情况,其中1%有双引号
Drakkim

8
"%~1"==""[]版本中不处理变量中的空格。
Cookie黄油2015年

17

一个更高级的示例:

⍟无限的争论。

⍟存在于文件系统(filedirectory?)或通用文件上string

⍟指定是否为文件

⍟指定是目录

没有扩展名,可以在旧脚本中使用!

最少的代码☺

@回声关闭

:循环
      :: --------------------------有论点吗?
      如果[“%〜1”] == [“”](
        回声完成。
        转到结尾
      )
      :: --------------------------参数存在吗?
      如果不存在%〜s1(
        回声不存在
      )其他(
        回声存在
        如果存在%〜s1 \ NUL(
          echo是一个目录
        )其他(
          回声是一个文件
        )
      )
      :: --------------------------
      转移
      转到循环
      
      
:结束

暂停

stuff其他东西..✨

■在%~1-在~删除任何包装"'

■在%~s1-将s使得路径是DOS 8.3 naming,这是一个很好的办法来避免空格的文件名,而检查的内容(而这种方式不需要更多的包裹资源"秒。

["%~1"]==[""]如果参数是文件/目录还是仅是通用字符串,则“不确定”,因此表达式使用方括号,而原始未修改%1"如果没有包装,则为自动包装。)

如果没有使用过的参数,shift并且arg-list指针已通过最后一个参数,则表达式将被计算为[""]==[""]

■这是您无需使用更多技巧就可以做到的特别具体(即使在Windows 95的批处理脚本中也可以使用...)

■执行实例

另存为 identifier.cmd

它可以识别无限个参数(通常只限于%1- %9),只记得记住用引号将它们包装起来,或者使用8.3命名或将其拖放(上面的操作会自动执行)。


这使您可以运行以下命令:

identifier.cmd c:\windows 和得到

存在
是一个目录
做完了

identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" 和得到

存在
是一个文件
做完了

⓷和多个参数(当然,这是全部交易。)

identifier.cmd c:\windows\system32 c:\hiberfil.sys "c:\pagefile.sys" hello-world

并得到

存在
是一个目录
存在
是一个文件
存在
是一个文件
不存在
完成。

自然,它可能要复杂得多, 但是好的示例应该总是简单而最少的。:)

希望它可以帮助任何人:)

在此处发布:CMD Ninja-无限参数处理,标识文件系统中是否存在,标识文件或目录

这是一个工作示例,该示例可以接收任意数量的APK文件(Android应用),并通过调试控制台(ADB.exe)将其安装到您的设备上: 使以前的帖子成为不使用ADB Install-Multi语法的Mass APK安装程序


14

摆脱括号。

样本批处理文件:

echo "%1"

if ("%1"=="") echo match1

if "%1"=="" echo match2

运行以上脚本的输出:

C:\>echo "" 
""

C:\>if ("" == "") echo match1 

C:\>if "" == "" echo match2 
match2

我认为实际上是将括号作为字符串的一部分,并且正在对其进行比较。


1
if "%1"==""如果arg有空格将崩溃。例如:run.bat "a b"。@amr是使用的最佳答案if "%~1"==""
wisbucky

6
IF "%~1"=="" GOTO :Usage

如果%1本身被引用,〜将取消对%1的引用。

“”可以防止传递的特殊字符。例如使用&ping调用脚本


1
这是最好的答案。其他答案在某些情况下有效,但在更特殊的情况下将失败,例如run.bat "a b"
wisbucky

@wisbucky似乎并没有弄乱公认的答案。我想念什么?
ruffin

@ruffin,示例:run.bat ""不会被抓住[%1]==[]
wisbucky


2

这与其他答案相同,但仅使用一个标签并将使用情况放在第一位,这另外使它成为脚本的一种文档推荐,通常也放在顶部:

@echo off
:: add other test for the arguments here...
if not [%1]==[] goto main
:: --------------------------
echo This command does something.
echo.
echo %0 param%%1 param%%2
echo       param%%1 the file to operate on
echo       param%%1 another file

:: --------------------------
exit /B 1

:main
:: --------------------------
echo do something with all arguments (%%* == %*) here...

但是,如果不必使用cmd / batch,则可以在WSL或powershell上使用bash,它们具有更合理的语法和更少的奥秘功能。


0

如果“%1” ==“”将失败,则此版本的所有版本在某些有毒字符条件下都会失败。只有“已定义”或“未定义”才是安全的


if [not] defined ...不适用于像这样的参数%1。你有一个例子,哪里if "%~1" ...不起作用?
斯蒂芬,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.