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

Posted

技术标签:

【中文标题】如何在启动/调用批处理文件时检查是不是定义了参数?【英文标题】:How can I check if an argument is defined when starting/calling a batch file?如何在启动/调用批处理文件时检查是否定义了参数? 【发布时间】:2010-10-24 06:04:49 【问题描述】:

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

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

@echo This should not execute

@echo Done.
goto :eof

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

我做错了什么?

【问题讨论】:

What is the proper way to test if a parameter is empty in a batch file?的可能重复 @double-beep - 这里的问题(由 daniel-fortunov 提出)是在您提到的问题发布前大约一年提出的。哪个是(可能的)重复项? @KevinFegan 因为另一个问题有更多的观点和更多的答案。 【参考方案1】:

检查是否设置了命令行参数可以是[%1]==[],但是Dave Costapoints out,"%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

【讨论】:

[%1]==[] 优于 "%1"=="" 因为它可以正确处理 %1 本身包含双引号的情况。 “%1”=="" 将出错并显示“此时意外”消息。 请注意,如果您使用的不是命令行参数而是set 变量(我不知道正确的批处理术语),您可能需要使用"%myvar%"=="",因为如果myvar 有里面有空格并且没有被引用,你会得到“unexpected at this time”的信息。 @Pat SET 变量可以用IF NOT DEFINED VarName 块检查。还 +1 对 tukushan 比较不使用引号。只是不要这样做。从不。 "%~1"=="" 也可以工作并处理 %1 有双引号的情况 "%~1"=="" 处理变量中的空格,而 [] 版本不处理。【参考方案2】:

一个更高级的例子:

⍟ 无限参数。

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

⍟指定是否为文件

⍟指定是一个目录

no 扩展,可以在旧脚本中使用!

最小代码☺

@echo 关闭 :环形 ::---------------------------- 有论据? 如果 ["%~1"]==[""] ( 回声完成。 转到结束 ) ::---------------------------- 参数存在吗? 如果不存在 %~s1 ( 回声不存在 ) 别的 ( 回声存在 如果存在 %~s1\NUL ( echo 是一个目录 ) 别的 ( 回声是一个文件 ) ) ::---------------------------- 转移 转到循环 :结尾 暂停

✨其他的东西..✨

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

■ 在%~s1 - s 使路径成为DOS 8.3 naming,这是在检查内容时避免文件名中的空格的好方法(这样就不需要用更多@987654333 包装资源@s.

["%~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 - Unlimited Arguments Processing, Identifying If Exist In File-System, Identifying If File Or Directory

这是一个工作示例,它获取任意数量的 APK 文件(android 应用程序)并通过调试控制台 (ADB.exe) 将它们安装在您的设备上: Make The Previous Post A Mass APK Installer That Does Not Uses ADB Install-Multi Syntax

【讨论】:

【参考方案3】:

去掉括号。

示例批处理文件:

echo "%1"

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

if "%1"=="" echo match2

运行上述脚本的输出:

C:\>echo "" 
""

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

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

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

【讨论】:

if "%1"=="" 如果 arg 有空格会崩溃。例如:run.bat "a b"。 @amr 有最好的答案来使用if "%~1"==""【参考方案4】:
IF "%~1"=="" GOTO :Usage

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

" " 将防止传递的特殊字符。例如用 &ping 调用脚本

【讨论】:

这是最好的答案。其他答案适用于某些情况,但对于更多特殊情况(如run.bat "a b")将失败 @wisbucky 这似乎并没有搞砸the accepted answer。我错过了什么? @ruffin,例如:run.bat "" 不会被[%1]==[] 捕获。【参考方案5】:

这与其他答案相同,但仅使用一个标签并将用法放在首位,这也使其作为脚本的一种文档推荐,通常也位于顶部:

@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,它们的语法更健全,神秘功能更少。

【讨论】:

【参考方案6】:
IF "%1"=="" GOTO :Continue
.....
.....
:Continue
IF "%1"=="" echo No Parameter given

【讨论】:

run.bat "a b" 崩溃【参考方案7】:

如果 "%1"=="" 将失败,则所有版本都将失败 某些毒字符条件。 只有 IF DEFINED 或 IF NOT DEFINED 才是安全的

【讨论】:

if [not] defined ... 不适用于%1 等参数。你有一个例子,if "%~1" ... 不起作用? 这是一个简单的代码注入示例。创建一个名为unsafe.bat 的文件,其内容为if "%~1"=="" ( echo hello )。现在从 Powershell 运行以下.\unsafe.bat "_`" neq `"`" echo Pwned &amp;::"。还使用社区答案 ***.com/a/34552964/1490584 运行相同的 Powershell 参数。您会看到默认情况下批处理参数非常不安全

以上是关于如何在启动/调用批处理文件时检查是不是定义了参数?的主要内容,如果未能解决你的问题,请参考以下文章

多处理时正确检查文件是不是存在

如何检查检查PInvoke签名的调用约定和参数与非托管的目标签名是不是匹配?

如何通过批处理文件检查服务是不是正在运行并启动它,如果它没有运行?

如何检查是不是设置了可选功能参数

Windows 7批处理文件:如何检查参数是不是已传递给批处理文件

如何传递运行时参数以从批处理文件启动 exe