在Windows批处理中检查空变量


67

我正在处理Windows批处理文件,它将批处理三个文本文件到SQL Server。如果生产中出现问题,我希望能够覆盖文件名。所以我正在考虑做这样的事情。

bcp.exe MyDB..MyTable1 in %1 -SMyServer -T -c -m0
bcp.exe MyDB..MyTable2 in %2 -SMyServer -T -c -m0
bcp.exe MyDB..MyTable3 in %3 -SMyServer -T -c -m0

我希望能够为所有三个文件输入默认名称,如果未提供位置参数,则可以使用默认名称。这个想法要么执行

myjob.bat

没有参数,并使用默认值或执行

myjob.bat "c:\myfile1" "c:\myfile2" "c:\myfile3"

并使用这些文件。我无法弄清楚如何判断%1,%2和%3是否存在和/或为空。我也不知道如何有条件地设置这些值。这可能吗?任何建议,将不胜感激。


任何对实现具有默认值的可选脚本参数感兴趣的人,都应该看一下有关Windows Bat文件可选参数解析问题的答案
dbenham

Answers:


125

要测试是否存在命令行参数,请使用方括号:

IF [%1]==[] echo Value Missing

要么

IF [%1] EQU [] echo Value Missing

IF上SS64页面将在这里为您提供帮助。在“%1是否存在?”下。

您无法设置位置参数,因此您应该做的是

SET MYVAR=%1

然后,您可以根据其内容重新设置MYVAR。


IF "%1"==""是不好的意思吗?
bryc '16

是,当arg1带有引号时,“%1”会生成语法错误,因此最好使用方括号。
莫什

28

给出的两个答案都是正确的,但我的确有所不同。您可能需要考虑几件事...

开始批处理:

SetLocal

并以

EndLocal

这将使您的所有“ SET”仅在当前会话期间有效,并且不会留下名称为“ FileName1”的var或在运行期间设置的任何其他变量,这可能会干扰批处理文件的下一次运行因此,您可以执行以下操作:

IF "%1"=="" SET FileName1=c:\file1.txt

另一个技巧是,如果您仅提供1个或2个参数,请使用SHIFT命令将其移动,因此,您一直在寻找的那个总是%1 ...

例如,处理第一个参数,移动它们,然后再次执行。这样,您就不会对%1,%2,%3等进行硬编码了。

在Windows批量处理器是很多更强大的比人们给它的信贷..我已经做了一些疯狂的事情吧,包括计算昨天的日期,甚至是跨月份和年份的界限,包括闰年和本地化等。

如果您真的想发挥创造力,则可以在批处理程序中调用函数...但这确实是一个不同的讨论... :)

哦,也不要将您的批处理文件命名为.bat ..现在它们是.cmd了

希望这可以帮助。


感谢您的建议。只是好奇...为什么用.cmd而不是.bat?
John M Gant

5
实际上,我认为这是一个抛砖引玉。BAT用于DOS,而CMD用于WinNT。。但是,真正的原因是一次您拥有cmd.exe和command.com。.cmd与cmd.exe有关,它是这些文件的解析器。我认为这也使您看起来更酷,但我无法确认。:)
LarryF

1
他们之间有微妙的区别,而且Raymond Chen有一则关于Old New Thing的帖子,我现在找不到... Google并不是我的朋友。另请参
见此

28

正确的做法是使用“如果已定义”语句,该语句用于测试变量的存在。例如:

IF DEFINED somevariable echo Value exists

在这种特殊情况下,应使用否定形式:

IF NOT DEFINED somevariable echo Value missing

PS:应使用不带“%”字符的变量名。


感谢你的回答。可以使用编号参数(例如在示例中使用)还是仅使用命名变量?
John M Gant

1,因为这个作品也,如果somevariable报价,同时IF [%somevariable%]==[]抛出一个错误。
Juan AntonioTubío2015年

@TerraAshley,因为不幸的是,这不适用于%1
Ameen

13
rem set defaults:
set filename1="c:\file1.txt"
set filename2="c:\file2.txt"
set filename3="c:\file3.txt"
rem set parameters:
IF NOT "a%1"=="a" (set filename1="%1")
IF NOT "a%2"=="a" (set filename2="%2")
IF NOT "a%3"=="a" (set filename1="%3")
echo %filename1%, %filename2%, %filename3%

但是,请小心引号字符,您的变量中可能需要也可能不需要。


2
+1; 几乎任何字符或字符串都可以:如果不是%1。== .; 如果不是{%1} == {};如果不是%1null == null ...
Patrick Cuff

1

答案较晚,但目前公认的答案至少不是最佳的。

使用引号总是比使用任何其他字符括起来更好%1
因为when%1包含空格或特殊字符(如)时&,会因IF [%1] ==语法错误而停止。

但是对于%1包含引号的情况(例如in)myBatch.bat "my file.txt",简单的操作IF "%1" == ""将失败。

但是,由于您不知道是否使用引号,因此存在语法%~1,可以在需要时删除封闭的引号。

因此,代码应类似于

set "file1=%~1"
IF "%~1"=="" set "file1=default file"

type "%file1%"   --- always enclose your variables in quotes

如果您必须处理像myBatch.bat "This & will "^&crash
这样的陌生人和更讨厌的参数,那么请看SO:如何甚至接收最奇怪的命令行参数?

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.