Nano Hash - криптовалюты, майнинг, программирование

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

Как мне создать папку (и любые подпапки) в пакетном скрипте? Но важно то, что если папка (или какие-либо подпапки) уже существуют, она не должна возвращать ошибку.

Например, примерно так:

  • mkdir mydir - успех (каталог создан)
  • mkdir mydir\subdir - успешно (теперь mydir содержит subdir)
  • mkdir mydir - успешно (папка уже существует, не должно выдавать ошибку)
  • mkdir mydir\subdir - успешно (папки уже существуют, не должно вызывать ошибку)

На самом деле мне нужно просто убедиться в существовании структуры папок.


  • mkdir mydir\subdir создаст mydir, если он еще не существует. Ошибка возникает, если последний компонент пути уже существует или если какой-либо компонент является файлом, а не каталогом. 05.07.2017
  • @eryksun Замечательно, что он создает mydir, если он еще не существует. Но я категорически не хочу получать ошибку, если последний компонент пути уже существует. 05.07.2017

Ответы:


1

Стандартный метод создания структуры каталогов:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "Directory=mydir\subdir 1\subdir 2"

md "%Directory%" 2>nul
if not exist "%Directory%\*" (
    echo Failed to create directory "%Directory%"
    pause
    goto :EOF
)

rem Other commands after successful creation of the directory.
endlocal

По умолчанию расширения команд включены, а отложенное раскрытие отключено. Пакетный код выше явно настраивает эту среду.

Команда MD создает полную структуру каталогов для указанного каталога с включенными расширениями команд.

MD выдает ошибку, если каталог уже существует. Это может быть полезно для информирования пользователя, вводящего команду вручную, о возможной ошибке во введенном пути к каталогу, поскольку возможно, что пользователь хотел создать новый каталог и по ошибке ввел имя уже существующего каталога.

Но при использовании команды MD в сценарии часто возникает проблема, когда эта команда выводит сообщение об ошибке, если каталог, который нужно создать, уже существует. Было бы действительно полезно, если бы в команде MD была возможность не выводить сообщение об ошибке в случае создания каталога, который уже существует, и выхода с кодом возврата 0 в этом случае. Но такого варианта нет.

Приведенное выше решение создает каталог и подавляет возможное сообщение об ошибке вывода, перенаправляя его с дескриптора STDERR на устройство NUL.

Но создание каталога может завершиться неудачно из-за недопустимого символа в пути к каталогу, диск недоступен (при использовании полного пути), в любом месте пути есть файл с именем указанного каталога, разрешения NTFS не разрешают создание каталога , и т.д.

Поэтому рекомендуется проверить, действительно ли существует каталог, что выполняется с помощью:

if not exist "%Directory%\*"

Важно, чтобы путь к каталогу теперь заканчивался \* или, по крайней мере, обратной косой чертой. В противном случае возможно, что в примере есть файл с именем subdir 2 в каталоге mydir\subdir 1, который при использовании условия if not exist "%Directory%" будет оцениваться как false, хотя каталога subdir 2 нет.

Конечно, также можно сначала выполнить проверку каталога и создать каталог, если он еще не существует.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "Directory=mydir\subdir 1\subdir 2"

if not exist "%Directory%\*" (
    md "%Directory%"
    if errorlevel 1 (
        pause
        goto :EOF
    )
)

rem Other commands after successful creation of the directory.
endlocal

Теперь пользователь может увидеть вывод сообщения об ошибке с помощью команды MD, если структура каталогов не может быть создана, с кратким объяснением причины.

Этот пакетный код можно было бы написать более компактно с помощью оператора ||:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "Directory=mydir\subdir 1\subdir 2"

if not exist "%Directory%\*" md "%Directory%" || (pause & goto :EOF)

rem Other commands after successful creation of the directory.
endlocal

Подробнее об операторах || и & читайте в ответе на Одна строка с несколькими командами с использованием командного файла Windows.

Команда ENDLOCAL не используется перед goto: EOF, поскольку для этой команды также требуются включенные расширения команд. Интерпретатор команд Windows выполняет эту команду неявно после выхода из выполнения командного файла.

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

  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • md /?
  • pause /?
  • set /?
  • setlocal /?

Прочтите также статью Microsoft об использовании операторов перенаправления команд.

06.07.2017
  • Спасибо за развернутый ответ. На самом деле жаль, что такая обычная операция (в сценариях) должна выполняться с таким количеством хлопот, в то время как она могла бы просто принять простой флаг (например). 08.07.2017
  • @steavy Согласен! Unix: mkdir -p путь / к / созданию Один уровень существует? Двигаться дальше. Windows: весь файл bat только для этого. Ппффф 30.11.2020

  • 2

    Вам нужно проверить путь и создать, если он не существует

    if not exist "mydir\subdir" md "mydir\subdir"
    

    Или вы также можете подавить сообщение об ошибке, перенаправив stderr

    md "mydir\subdir" 2>NUL
    

    Вам не нужно сначала запускать mkdir mydir, потому что

    Расширения команд, которые включены по умолчанию, позволяют использовать одну команду md для создания промежуточных каталогов по указанному пути.

    https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/md

    См. Также https://ss64.com/nt/md.html.

    05.07.2017
  • Вы не можете игнорировать ошибку, если одним из компонентов пути является файл, а не каталог. Нельзя допустить, чтобы это молча проходило как успешное. Например, mkdir name1\name2\name3_is_a_file\name4. 05.07.2017
  • Я считаю эти два решения слишком сложными для такой простой задачи, как создание каталога. Они больше похожи на обходные пути. Мне интересно, есть ли простое решение, такое как какой-либо флаг конфигурации или другая команда, которая имеет желаемое поведение. 05.07.2017
  • @steavy - Если вы находите эти решения слишком сложными, вам следует отказаться от пакетной работы сейчас. 05.07.2017
  • @eryksun - Интересный крайний случай. Имена файлов без расширения встречаются редко, но я понимаю вашу точку зрения. Жаль, что УРОВЕНЬ ОШИБКИ одинаков для существующего файла и существующей папки. 05.07.2017
  • Решение @Mofi md mydir\subdir 2>NUL мне не подходит, потому что я не хочу подавлять все возможные ошибки. Я просто не хочу получать сообщение об ошибке, если такая папка уже существует. Точно так же, как вы написали, просто имеет значение, существует ли каталог после выполнения командной строки ». Если возникла системная ошибка, которая помешала созданию папки, я все равно хотел бы получить сообщение об ошибке, потому что это будет означать, что моя папка не создана. Но если папка уже была там - мне все равно, я в порядке. Вы понимаете мою точку зрения? 06.07.2017
  • моя работа все еще терпит неудачу даже с 2 ›nul все еще вызывает ошибку внутри jenkins 05.05.2021
  • @pelos, тогда есть другие проблемы, такие как разрешение, которые вам нужно проверить, запустив md без перенаправления stderr. См. Ответ Мофи выше 05.05.2021
  • спасибо @phuclv перенаправление на nul, если папка все еще была, код ошибки 1 и это изменило весь рабочий процесс, я смог сделать bat, если артефакт md артефакт не существует, и это решит его =) 05.05.2021
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..