【问题标题】:Check for null variable in Windows batch检查 Windows 批处理中的空变量
【发布时间】:2010-10-18 09:30:01
【问题描述】:

我正在处理一个 Windows 批处理文件,它将三个文本文件 bcp 到 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 batch-file


【解决方案1】:

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

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

或

IF [%1] EQU [] echo Value Missing

SS64 page on IF 将在这里为您提供帮助。在“%1 存在吗?”下。

你不能设置位置参数,所以你应该做的是像

SET MYVAR=%1

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

【讨论】:

  • 这是否意味着IF "%1"=="" 不好?
  • 是的 "%1" 当 arg1 有引号时会产生语法错误,所以最好使用方括号。
【解决方案2】:
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%

请注意引号字符,您的变量中可能需要也可能不需要它们。

【讨论】:

  • +1;几乎任何字符或字符串都可以:如果不是 %1.==.;如果不是 {%1}=={};如果不是 %1null==null...
【解决方案3】:

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

使用以下命令开始批处理:

SetLocal

并以

结束
EndLocal

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

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

另一个技巧是,如果您只提供 1 个或 2 个参数,请使用 SHIFT 命令移动它们,因此您要查找的参数始终位于 %1...

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

Windows 批处理器比人们认为的要强大得多。我用它做了一些疯狂的事情,包括计算昨天的日期,甚至跨越月份和年份的界限,包括闰年,以及本地化等。

如果你真的想发挥创意,你可以在批处理器中调用函数......但这真的是另一种讨论...... :)

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

希望这会有所帮助。

【讨论】:

  • 感谢您的建议。只是好奇...为什么 .cmd 而不是 .bat?
  • 实际上,我认为这是一个倒退。 BAT 用于 DOS,CMD 用于 WinNT。但是,真正的原因是,曾经有 cmd.exe 和 command.com。 .cmd 与 cmd.exe 有关,它是那些的解析器。我认为这也让你看起来更酷,但我无法证实这一点。 :)
  • 它们之间存在细微差别,Raymond Chen 有一篇关于它的旧新事物的帖子,我现在找不到... Google 不是我的朋友。另请参阅此 SO Q:stackoverflow.com/questions/148968/…
【解决方案4】:

正确的做法是使用“if defined”语句,用于测试变量是否存在。例如:

IF DEFINED somevariable echo Value exists

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

IF NOT DEFINED somevariable echo Value missing

PS:变量名不能使用“%”字符。

【讨论】:

  • 感谢您的回答。这适用于编号参数,就像我在我的示例中使用的那样,还是仅适用于命名变量?
  • +1 因为如果somevariable 有 quotes 而IF [%somevariable%]==[] 抛出一个错误,这也有效。
  • @TerraAshley 因为不幸的是,这不适用于 %1
【解决方案5】:

迟到的答案,但目前被接受的答案至少不是最理想的。

使用引号总是比使用任何其他字符括住%1 更好。
因为当%1 包含空格或& 之类的特殊字符时,IF [%1] == 只会因语法错误而停止。

但是对于%1 包含引号的情况,例如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:How to receive even the strangest command line parameters?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-19
    • 1970-01-01
    相关资源
    最近更新 更多