2009-09-11 65 views
3

你好,我正在写一个批处理脚本将运行在一台Windows XP机器上。该脚本需要能够可靠地验证作为命令行参数传递的目录确实存在。如何通过WinXP批处理脚本可靠地验证目录的存在?

假设我的脚本被命名为script.bat,它需要支持下列法律命令行参数:

C:\> script.bat C: 
C:\> script.bat C:\ 
C:\> script.bat ..\photos 
C:\> script.bat C:\WINDOWS 
C:\> script.bat "C:\Documents and Settings" 
C:\> script.bat "C:\Documents and Settings\" 
C:\> script.bat F:\music\data\ 
C:\> ... 

基本上,它必须是法律给一个驱动器号,有或无尾部反斜杠以及完整,绝对或相对路径名称,带或不带尾部反斜杠(并且在某些目录名称中有或没有空格)。名称MUST很明显,如果它包含空格以便被解释为一个参数。然而,报价应该在名字被允许在那里他们不是另有规定:

C:\> script.bat "F:\music\data\" 

我第一次尝试是这样的:

@ECHO OFF 
SETLOCAL EnableExtensions EnableDelayedExpansion 
IF ErrorLevel 1 GOTO :NoExtensions 
IF "%~1"=="" GOTO :NoDirectory 

SET dir=%~1\NUL 
ECHO You provided: %1 
ECHO Testing using: %dir% 
IF NOT EXIST %dir% GOTO :BadDirectory 
SET dir=%~f1\ 
ECHO The following is valid: %dir% 

REM 
REM Other script stuff here... 
REM 

GOTO :EOF 
:NoExtensions 
    ECHO This batch script requires extensions! 
    GOTO :EOF 
:NoDirectory 
    ECHO You must provide a directory to validate! 
    GOTO :EOF 
:BadDirectory 
    ECHO The directory you specified is invalid! 

主要的问题是,它不工作时被指定具有嵌入空格的路径:

C:\script.bat "C:\Documents and Settings" 
... 
'and' is not recognized as an internal or external command, 
operable program or batch file. 

所以,我试图引述%DIR%变量如下:

IF NOT EXIST "%dir%" GOTO :BadDirectory 

当使用“IF NOT EXIST”直接检查文件时,上述引用似乎有效,但在使用“dir \ NUL”技巧检查目录时,它根本不起作用。

原始版本中的另一个小故障是,如果%1是C:那么%〜f1版本的变量总是会产生我当前的工作目录而不是C:或C:\,因为这样会更有用。我并不确定解决这个问题的最佳方法。

任何帮助或意见将很大赞赏!

- 签名:真希望我写的bash shell脚本,红宝石,或其他任何东西,而不是...

+0

是否需要使用批处理文件? Windows PowerShell是一个强大的选择。我会考虑使用PowerShell进行命令行脚本的未来发展。 – AMissico 2009-09-12 00:10:16

+0

PowerShell的缺点是没有包含在较旧的和陈旧的Windows版本中。 – Joey 2009-09-12 07:22:39

+0

他的要求是“Windows XP机器”。 – AMissico 2009-09-12 07:53:17

回答

8

我已经找到工作了一个批处理文件的解决方案。它根本不涉及使用IF EXIST,而是滥用PUSHD。我试图哄骗IF EXIST工作,但在90%的失败和50%的成功之间摇摆不定。呸。然后我注意到我可以尝试进入该目录来检查它是否存在。这受限于像检查“dir \ nul”一样的限制,因为您需要权限才能查看目录。例如,这两种尝试都会失败,例如系统卷信息。但这不是问题。

因此,CDPUSHD都是非常聪明的,当涉及到找出目录,它像一个魅力。 (注意:所有代码,包括测试都可以在my SVN中找到)。

@echo off 
setlocal enableextensions 
rem this one works reliably 
if "%~1"=="" goto NoDirectory 

pushd %1 2>nul && popd || goto :BadDirectory 

echo DOES EXIST 

endlocal 
goto :eof 

:NoDirectory 
echo NO DIR 
exit /b 1 

:BadDirectory 
echo DOES NOT EXIST 
exit /b 1 

后,我得到了我所有的测试用例右它非常漂亮:

SUMMARY 
    Succeeded: 60 
    Failed: 0 
    ----------------- 
    Total:  60 

你问前:是的,我已经做单元测试的批处理文件在这里。有人请杀了我。

另一个说明:我在setlocal之后省略了错误检查,因为如果您打算在DOS或Windows 9x/ME上运行脚本,您只需要这样做。由于这不可能工作,我倾向于总是命名我的批处理文件.cmd而不是.batAMissico指出,以及,但出于错误的原因。 .cmd作为扩展的好处是,DOS和WinDOS都不会尝试执行它。不需要包含错误处理,然后:-)然而,一般来说,我认为你最好使用VBScript来完成这些任务。自Windows 98以来,Windows Script Host已包含在所有版本的Windows中(甚至Win 7仍有它:-)),因此它是一个可靠的平台。

4

更改存在测试使用\*而不是\NUL,那么你可以引用路径。至于C:问题消失,只是用"%~1\*"应该总是工作(Windows可以处理c:\\*c:\folder\\*

你也应该注意到,在比其他任何形式的存储路径“%〜[国旗] 1”可能会导致问题如果路径中包含一个或多个% ! _^(space)