Как я могу надежно проверить существование каталога с помощью пакетного скрипта WinXP? - PullRequest
3 голосов
/ 12 сентября 2009

Привет, я пишу пакетный скрипт , который будет работать на 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!

Проблема main в том, что она не работает, если указан путь со встроенными пробелами:

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

Заключение в кавычки, как указано выше, работает при использовании «ЕСЛИ НЕ СУЩЕСТВУЕТ» для прямой проверки файлов, но не работает вообще при использовании трюка «dir \ NUL» для проверки каталогов.

Другой недостаток в исходной версии заключается в том, что если% 1 - это C: тогда версия переменной% ~ f1 всегда, кажется, дает мой текущий рабочий каталог вместо C: или C: \, как было бы более полезно. Я не совсем уверен, что лучший способ обойти это тоже.

Любая помощь или комментарии будут очень оценили!

- Подпись: жаль, что я вместо этого писал сценарии оболочки bash, ruby ​​или что-то еще ...

Ответы [ 2 ]

8 голосов
/ 12 сентября 2009

Я нашел рабочее решение для командного файла. Это вовсе не связано с использованием IF EXIST, а скорее злоупотребляет PUSHD. Я немного возился с попыткой заставить IF EXIST работать, но колебался между 90% неудачей и 50% успехом. Тьфу. Затем я заметил, что могу попробовать зайти в этот каталог, чтобы проверить, существует ли он. Это подчиняется тем же ограничениям, что и проверка на наличие «dir \ nul», так как вам нужны разрешения для просмотра каталога. Обе попытки терпят неудачу с такими вещами, как System Volume Information, например. Но это не проблема здесь.

Так что 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. Хост скриптов Windows включен во все версии Windows начиная с 98 (даже в Win 7 он есть :-)), и поэтому он является надежной платформой.

4 голосов
/ 15 сентября 2009

Измените существующий тест, чтобы использовать \*, а не \NUL, тогда вы можете указать путь. Что касается проблемы c: просто использование "%~1\*" должно работать всегда (Windows может обрабатывать c:\\* и c:\folder\\*)

Следует также отметить, что сохранение пути в любой форме, кроме "% ~ [flags] 1", может вызвать проблемы, если путь содержит один или несколько из % ! _ ^ (space)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...