在 Windows 批处理中检查空变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/731332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check for null variable in Windows batch
提问by John M Gant
I'm working on a Windows batch file that will bcp three text files into SQL Server. If something goes wrong in production, I want to be able to override the file names. So I'm thinking of doing something like this.
我正在处理一个 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
I would like to be able to enter default names for all three files, to be used if the positional parameters are not supplied. The idea would be either to execute
我希望能够为所有三个文件输入默认名称,以便在未提供位置参数时使用。这个想法要么是执行
myjob.bat
with no parameters, and have it use the defaults, or execute
不带参数,让它使用默认值,或者执行
myjob.bat "c:\myfile1" "c:\myfile2" "c:\myfile3"
and have it use those files. I haven't been able to figure out how to tell if %1, %2 and %3 exist and/or are null. I also don't know how to set those values conditionally. Is this possible? Any suggestions would be appreciated.
并让它使用这些文件。我一直无法弄清楚如何判断 %1、%2 和 %3 是否存在和/或为空。我也不知道如何有条件地设置这些值。这可能吗?任何建议,将不胜感激。
回答by crb
To test for the existence of a command line paramater, use empty brackets:
要测试命令行参数是否存在,请使用空括号:
IF [%1]==[] echo Value Missing
or
或者
IF [%1] EQU [] echo Value Missing
The SS64 page on IFwill help you here. Under "Does %1 exist?".
IF 上的SS64 页面将在这里为您提供帮助。在“%1 是否存在?”下。
You can't set a positional parameter, so what you should do is do something like
你不能设置位置参数,所以你应该做的是做类似的事情
SET MYVAR=%1
You can then re-set MYVAR based on its contents.
然后您可以根据其内容重新设置 MYVAR。
回答by LarryF
Both answers given are correct, but I do mine a little different. You might want to consider a couple things...
给出的两个答案都是正确的,但我的答案略有不同。你可能需要考虑一些事情......
Start the batch with:
开始批处理:
SetLocal
and end it with
并以
EndLocal
This will keep all your 'SETs" to be only valid during the current session, and will not leave vars left around named like "FileName1" or any other variables you set during the run, that could interfere with the next run of the batch file. So, you can do something like:
这将使您的所有“SET”仅在当前会话期间有效,并且不会留下诸如“FileName1”之类的变量或您在运行期间设置的任何其他变量,这可能会干扰批处理文件的下一次运行. 因此,您可以执行以下操作:
IF "%1"=="" SET FileName1=c:\file1.txt
The other trick is if you only provide 1, or 2 parameters, use the SHIFT command to move them, so the one you are looking for is ALWAYS at %1...
另一个技巧是,如果您只提供 1 个或 2 个参数,请使用 SHIFT 命令移动它们,因此您要查找的参数始终位于 %1...
For example, process the first parameter, shift them, and then do it again. This way, you are not hard-coding %1, %2, %3, etc...
例如,处理第一个参数,移动它们,然后再做一次。这样,您就不会硬编码 %1、%2、%3 等...
The Windows batch processor is muchmore powerful than people give it credit for.. I've done some crazy stuff with it, including calculating yesterday's date, even across month and year boundaries including Leap Year, and localization, etc.
在Windows批量处理器是很多更强大的比人们给它的信贷..我已经做了一些疯狂的事情吧,包括计算昨天的日期,甚至是跨月份和年份的界限,包括闰年和本地化等。
If you really want to get creative, you can call functions in the batch processor... But that's really for a different discussion... :)
如果你真的想发挥创意,你可以在批处理器中调用函数......但这真的是一个不同的讨论...... :)
Oh, and don't name your batch files .bateither.. They are .cmd's now.. heh..
哦,也不要将您的批处理文件命名为.bat.. 它们现在是.cmd的 .. heh..
Hope this helps.
希望这可以帮助。
回答by Leonardo Puglia
The right thing would be to use a "if defined" statement, which is used to test for the existence of a variable. For example:
正确的做法是使用“if defined”语句,该语句用于测试变量是否存在。例如:
IF DEFINED somevariable echo Value exists
In this particular case, the negative form should be used:
在这种特殊情况下,应使用否定形式:
IF NOT DEFINED somevariable echo Value missing
PS: the variable name should be used without "%" caracters.
PS:变量名应该不带“%”字符使用。
回答by Stanislav Kniazev
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%
Be careful with quotation characters though, you may or may not need them in your variables.
但是要小心引号字符,您可能需要也可能不需要它们在您的变量中。
回答by jeb
Late answer, but currently the accepted one is at least suboptimal.
迟到的答案,但目前接受的答案至少是次优的。
Using quotes is ALWAYS better than using any other characters to enclose %1
.
Because when %1
contains spaces or special characters like &
, the IF [%1] ==
simply stops with a syntax error.
使用引号总是比使用任何其他字符来括起来更好%1
。
因为当%1
包含空格或特殊字符(如 )时&
,IF [%1] ==
只会因语法错误而停止。
But for the case that %1
contains quotes, like in myBatch.bat "my file.txt"
, a simple IF "%1" == ""
would fail.
但是对于%1
包含引号的情况,比如 in myBatch.bat "my file.txt"
,一个简单的IF "%1" == ""
会失败。
But as you can't know if quotes are used or not, there is the syntax %~1
, this removes enclosing quotes when necessary.
但是由于您不知道是否使用了引号,因此有语法%~1
,这会在必要时删除封闭的引号。
Therefore, the code should look like
因此,代码应该看起来像
set "file1=%~1"
IF "%~1"=="" set "file1=default file"
type "%file1%" --- always enclose your variables in quotes
If you have to handle stranger and nastier arguments like myBatch.bat "This & will "^&crash
Then take a look at SO:How to receive even the strangest command line parameters?
如果你必须处理陌生和更讨厌的参数,myBatch.bat "This & will "^&crash
那么看看SO:如何接收最奇怪的命令行参数?