你好,我正在写一个批处理脚本,它将在 Windows XP 机器上运行。该脚本需要能够可靠地验证作为命令行参数传递的目录确实存在。
假设我的脚本名为 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:\> ...
基本上,提供驱动器号(带有或不带有尾部反斜杠以及完整,绝对或相对路径名),带有或不带有尾部反斜杠(在某些目录名称中带有或不带有空格)都必须合法。 ))。显然,如果名称包含空格,则必须用引号将其解释为一个参数。但是,应在没有其他要求的名称上加上引号:
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脚本,ruby或其他任何东西...
最佳答案
我找到了批处理文件的工作解决方案。它根本不涉及使用IF EXIST
,而是滥用PUSHD
。我尝试哄骗IF EXIST
正常工作时摸索了一下,但在90%失败和50%成功之间摇摆不定。 uck然后我注意到我可以尝试实际进入该目录检查它是否存在。这受到几乎相同的限制,例如检查“dir\nul”是否存在,因为您需要查看目录内部的权限。两次尝试都失败,例如出现系统卷信息。但这不是这里的问题。
因此,在查找目录时,CD
和PUSHD
都非常聪明,它的工作原理就像一个魅力。
(注意:包括测试在内的所有代码都可以在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
而不是.bat
。 AMissico也指出了这一点,但是出于错误的原因。 .cmd
作为扩展名的好处是DOS和WinDOS都不会尝试执行它。无需包括错误处理,然后:-)但是,总的来说,我认为最好将VBScript用于此类任务。自98年以来,Windows Script Host包含在所有版本的Windows中(即使Win 7仍具有它:-)),因此它是一个非常可靠的平台。