Создать папку с пакетом, но только если она еще не существует


441

Кто-нибудь может сказать мне, как сделать следующее в пакетном скрипте Windows? ( *.bat):

  • Создать папку, только если она еще не существует

Более подробно, я хочу создать папку с именем VTSна C:\диске, но только если эта папка еще не существует. Я не хочу перезаписывать содержимое папки, если она уже существует и пакет выполняется.


2
Как насчет этого ? if not exist "%Folder%" mkdir "%New-Folder%"
scientist_7

Ответы:


622

Вы просто используете это: if not exist "C:\VTS\" mkdir C:\VTSон создаст каталог, только если папка не существует.

Обратите внимание, что этот тест на существование вернет true, только если VTS существует и является каталогом. Если его там нет или он есть в виде файла, команда mkdir будет запущена и должна вызвать ошибку. Возможно, вы захотите проверить, существует ли VTS в виде файла.


7
За исключением того, что это неправильно. Вы должны проверить устройство NUL, иначе оно не будет работать. Смотрите мой ответ на три года раньше, чем этот.
Мартин Шапендонк,

@MartinSchapendonk Насколько я могу судить по результатам тестирования, это работает в Windows 7 и Windows Server 2012, и я был бы очень удивлен, если бы он не работал по крайней мере до XP и до Windows 10. Можете ли вы предоставить условия, когда это не работает?
jpmc26

12
@ jpmc26 тестирование на NUL - это проверка каталога. В противном случае условие может быть оценено как истинное, даже если это обычный файл. В этом разница.
Мартин Шапендонк

3
@MartinSchapendonk Достаточно ли для этого добавления косой черты? Кажется, это правильно различает файлы и каталоги, но есть недостаток в том, что если файл не обнаружен, создание каталога завершится неудачно. Я подозреваю, что это проблема с тестированием NULтоже.
jpmc26

6
@ jpmc26 Вы правы, конечный слеш делает свою работу и на самом деле предпочтительнее, поскольку работает с кавычками (что позволяет вам иметь пробелы в пути к каталогу). Для того, чтобы различать либо файл / каталог, это будет работать: if exist "a" if not exist "a\" (echo "it's a file") else (echo "it's a dir"). Что касается вашего последнего предложения, я подозреваю, что что-то не так с вашим командным файлом в другом месте.
23 марта

223
if exist C:\VTS\NUL echo "Folder already exists"

if not exist C:\VTS\NUL echo "Folder does not exist"

Смотрите также https://support.microsoft.com/en-us/kb/65994

(Обновление от 7 марта 2018 года; статья Microsoft недоступна, архив на https://web.archive.org/web/20150609092521/https://support.microsoft.com/en-us/kb/65994 )


12
Лично я предпочел бы это, так как он не устанавливает% errorlevel%, когда dir уже существует (ответ Agent_9191 возвращает код ошибки 1)
csauve

1
Это также хорошо и универсально и может быть применено к любому другому действию, которое вы хотите сделать условно :)
Джон Хамфрис - w00te

3
@YouHaveaBigEgo NULс одним Л.
Мартин Шапендонк

1
Ссылка больше не работает, но есть копия в интернет-архиве
fernio

3
На самом деле, хотя этот ответ великолепен, он не отвечает на вопрос «создать каталог» :)
Жан-Франсуа Т.

55

Просто позвони, mkdir C:\VTSнесмотря ни на что. Он просто сообщит, что подкаталог уже существует.

Редактировать: Как уже отмечалось, это устанавливает% ERRORLEVEL%, если папка уже существует. Если ваш пакет (или любой вызывающий его процесс) не заботится об уровне ошибок, этот метод работает хорошо. Поскольку в вопросе не упоминалось о том, как избежать уровня ошибок, этот ответ является совершенно верным. Он удовлетворяет потребности создания папки, если она не существует, и не перезаписывает содержимое существующей папки. В противном случае следуйте ответу Мартина Шапендонка .


20
это плохое поведение из-за неожиданного сообщения об ошибке / предупреждения.
SeriousM

11
Называть что-то «совершенно обоснованным», когда оно нарушает лучшие практики, интеллектуально нечестно. Другой пример: когда кто-то спрашивает вас, как избежать определенной конкретной проблемы безопасности, ваш ответ не должен быть «запускать компьютер от имени администратора», даже если в вопросе явно не указано минимальное влияние на безопасность в качестве предварительного условия. :-)
Джуни Хейкниеми

2
@JouniHeikniemi s / лучшие практики / личные предпочтения
Джоуни

4
Ничего плохого в Errorlevel или errno. Это парадигмы обмена сообщениями об ошибках, специфичные для платформы, и они работают для цели, для которой они созданы. Но независимо от того, какова платформа или подход к обмену сообщениями, я бы не рекомендовал шаблон «попытаться сделать это и восстановить, если он потерпит неудачу», когда вы можете легко избежать - и, таким образом, разборчиво документировать - распространенную ошибку. Следовательно, я считаю, что стиль «если не существует» подходит лучше. Но я не хочу или не хочу слишком углубляться в дебаты о формировании лучших практик. Я не собирался никого обидеть, просто хотел уточнить свой голос.
Джуни Хейкниеми

4
Проблема с простым игнорированием ошибки заключается в том, что вы не знаете, почему она произошла . Это могло произойти сбой, потому что каталог уже существует, потому что у пользователя нет разрешений на этот каталог, потому что родительский путь не существует, или потому, что диск вышел из строя. «Создать, если его не существует» должно завершиться неудачей во всех случаях, кроме первого. Этот ответ приводит к ошибке во всех случаях. Вот почему это не подходит для пакетного сценария. -1
jpmc26

38
mkdir C:\VTS 2> NUL

создайте папку с именем VTSи выведите A subdirectory or file TEST already existsв NUL.

или

(C:&(mkdir "C:\VTS" 2> NUL))&

измените букву диска на C:, mkdirвыведите ошибку NULи выполните следующую команду.


Есть ли способ заставить это работать в PowerShell? Кажется, он не поддерживается NULв качестве выходного файла.
Аарон Франке

30
set myDIR=LOG
IF not exist %myDIR% (mkdir %myDIR%)

1
Как отмечали другие, и вы, возможно, видели в ответе с самым высоким рейтингом, это не работает, если у вас есть файл с именем log. Это небольшая разница, но она приведет к трудным для поиска ошибкам в ваших скриптах.
Авель

20

Я использую этот способ, вы должны поставить обратную косую черту в конце имени каталога, чтобы избежать того, что место существует в файле без расширения с тем же именем, что и указанный вами каталог, никогда не используйте «C: \ VTS», потому что это может файл существует с именем «VTS», сохраненным в разделе «C:» , правильный способ - использовать «C: \ VTS \» , проверить обратную косую черту после VTS , так что это правильный путь.

@echo off
@break off
@title Create folder with batch but only if it doesn't already exist - D3F4ULT
@color 0a
@cls

setlocal EnableDelayedExpansion

if not exist "C:\VTS\" (
  mkdir "C:\VTS\"
  if "!errorlevel!" EQU "0" (
    echo Folder created successfully
  ) else (
    echo Error while creating folder
  )
) else (
  echo Folder already exists
)

pause
exit

3
Что особенно интересно в вашем решении, это то, что вы используете !errorlevel!, то есть отложенное расширение. В противном случае переменная ERRORLEVELбудет проанализирована до ввода первого if(т. Е. Во время разбора). Теперь он анализируется во время выполнения, поэтому он может захватить результат mkdir. Вы также правы в этом, даже если вы проверяете на существование, вы все равно должны проверять на успех (например, подумайте: ошибка доступа запрещена). Очень хорошее решение по сравнению с другими, +10 !!!
Авель

17

Ты можешь использовать:

if not exist "C:\VTS\" mkdir "C:\VTS"

Вы также можете расширить код, чтобы заменить любые отсутствующие ожидаемые файлы.

if not exist "C:\VTS\important.file" echo. > "C:\VTS\important.file"

0

я создал это для своего сценария, который я использую в своей работе для глазного луча.

:CREATES A CHECK VARIABLE

set lookup=0

:CHECKS IF THE FOLDER ALREADY EXIST"

IF EXIST "%UserProfile%\AppData\Local\CounterPath\RegNow Enhanced\default_user\" (set lookup=1)

:IF CHECK is still 0 which means does not exist. It creates the folder

IF %lookup%==0 START "" mkdir "%UserProfile%\AppData\Local\CounterPath\RegNow Enhanced\default_user\"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.