Utwórz folder z pakietem, ale tylko wtedy, gdy jeszcze nie istnieje

440

Czy ktoś może mi powiedzieć, jak wykonać następujące czynności w skrypcie wsadowym systemu Windows? ( *.bat):

  • Utwórz folder tylko wtedy, gdy jeszcze nie istnieje

Bardziej szczegółowo chcę utworzyć folder o nazwie VTSna C:\dysku, ale tylko wtedy, gdy ten folder jeszcze nie istnieje. Nie chcę nadpisywać zawartości folderu, jeśli już istnieje i partia jest wykonywana.

Rachunek
źródło
2
Co powiesz na to ? if not exist "%Folder%" mkdir "%New-Folder%"
scientist_7

Odpowiedzi:

622

Po prostu użyj tego: if not exist "C:\VTS\" mkdir C:\VTSutworzy katalog tylko wtedy, gdy folder nie istnieje.

Należy pamiętać, że ten test istnienia zwróci wartość true tylko wtedy, gdy VTS istnieje i jest katalogiem. Jeśli nie ma go lub istnieje jako plik, uruchomi się polecenie mkdir, które powinno spowodować błąd. Możesz sprawdzić, czy VTS istnieje również jako plik.

Odpowiadający
źródło
7
Tyle że to źle. Musisz sprawdzić urządzenie NUL, w przeciwnym razie nie będzie działać. Zobacz moją odpowiedź trzy lata wcześniej niż ta.
Martin Schapendonk
@MartinSchapendonk Działa to w systemach Windows 7 i Windows Server 2012, o ile wiem z testów, i byłbym bardzo zaskoczony, gdyby nie działał przynajmniej w wersji XP i Windows 10. Czy możesz podać warunki, w których to nie działa?
jpmc26
12
@ Testowanie jpmc26 pod kątem NUL ma na celu sprawdzenie, czy istnieje katalog. W przeciwnym razie warunek może być spełniony, nawet jeśli jest to zwykły plik. To jest różnica.
Martin Schapendonk,
3
@MartinSchapendonk Czy dodanie ukośnika końcowego jest do tego wystarczające? Wydaje się, że prawidłowo rozróżnia pliki i katalogi, ale istnieje pewna słabość polegająca na tym, że jeśli plik nie zostanie wykryty, utworzenie katalogu zakończy się niepowodzeniem. Podejrzewam, że jest to również problem z testowaniem NUL.
jpmc26
6
@ jpmc26 Masz rację, ukośnik końcowy wykonuje zadanie i jest właściwie preferowany, ponieważ działa z cudzysłowami (umożliwiając w ten sposób spacje w ścieżce katalogu). Rozróżnić obu plików / katalogu, to będzie działać: if exist "a" if not exist "a\" (echo "it's a file") else (echo "it's a dir"). Jeśli chodzi o twoje ostatnie zdanie, podejrzewam, że coś jest nie tak z plikiem wsadowym w innym miejscu.
Marc.2377,
221
if exist C:\VTS\NUL echo "Folder already exists"

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

Zobacz także https://support.microsoft.com/en-us/kb/65994

(Aktualizacja z 7 marca 2018 r .; artykuł Microsoft nie działa, archiwum na https://web.archive.org/web/20150609092521/https://support.microsoft.com/en-us/kb/65994 )

Martin Schapendonk
źródło
12
Osobiście wolałbym to, ponieważ nie ustawia% poziomu błędu%, gdy katalog już istnieje (odpowiedź Agent_9191 zwraca kod błędu 1)
csauve
1
Jest także miły i ogólny i można go zastosować do każdej innej czynności, którą chcesz warunkowo wykonać :)
John Humphreys - w00te
3
@YouHaveaBigEgo NULjest z jednym L.
Martin Schapendonk
1
Link już nie działa, ale jego kopia
fernio
3
W rzeczywistości, chociaż ta odpowiedź jest świetna, nie odpowiada na pytanie „stworzyć katalog” :)
Jean-Francois T.,
55

Po prostu zadzwoń mkdir C:\VTSbez względu na wszystko. Po prostu zgłosi, że podkatalog już istnieje.

Edycja: jak zauważyli inni, ustawia% ERRORLEVEL%, jeśli folder już istnieje. Jeśli twoja partia (lub jakikolwiek proces ją nazywający) nie dba o poziom błędu, ta metoda działa dobrze. Ponieważ w pytaniu nie wspomniano o unikaniu poziomu błędu, ta odpowiedź jest całkowicie poprawna. Spełnia potrzeby tworzenia folderu, jeśli nie istnieje, i nie zastępuje zawartości istniejącego folderu. W przeciwnym razie podążaj za odpowiedzią Martina Schapendonka .

Agent_9191
źródło
20
jest to złe zachowanie z powodu nieoczekiwanego komunikatu o błędzie / ostrzeżenia.
SeriousM
10
Nazwanie czegoś „całkowicie poprawnym”, gdy narusza ono najlepsze praktyki, jest intelektualnie nieuczciwe. Jako inny przykład: gdy ktoś zapyta Cię, jak uniknąć określonego problemu z zabezpieczeniami, twoja odpowiedź nie powinna brzmieć: „uruchom komputer jako administrator”, nawet jeśli pytanie nie określa wprost minimalnego wpływu na bezpieczeństwo jako warunku wstępnego. :-)
Jouni Heikniemi
2
@JouniHeikniemi s / najlepsze praktyki / osobiste preferencje Jouni
dss539
4
Nic złego z poziomem błędu lub błędem. Są to specyficzne dla platformy paradygmaty komunikatów o błędach i działają zgodnie z przeznaczeniem. Ale bez względu na platformę lub podejście do przesyłania komunikatów, nie zalecałbym wzorca „spróbuj to zrobić i odzyskaj, jeśli się nie powiedzie”, gdy można łatwo uniknąć - a tym samym czytelnie udokumentować - typowego błędu. Dlatego uważam, że styl „jeśli nie istnieje” zbliża się do przełożonego. Ale nie chcę lub nie chcę zbyt głęboko angażować się w debatę na temat tworzenia najlepszych praktyk. Nie miałem zamiaru nikogo urazić, chciałem tylko wyjaśnić swoją opinię.
Jouni Heikniemi,
4
Problem z po prostu ignorowaniem błędu polega na tym, że nie wiesz, dlaczego się nie udało. Mogło się to nie udać, ponieważ katalog już istniał, ponieważ użytkownik nie ma uprawnień do tego katalogu, ponieważ ścieżka nadrzędna nie istniała lub dysk uległ awarii. „Utwórz, jeśli nie istnieje” powinno zakończyć się niepowodzeniem we wszystkich przypadkach oprócz pierwszego. Ta odpowiedź powoduje jednak błąd we wszystkich przypadkach. Dlatego nie nadaje się do skryptu wsadowego. -1
jpmc26
38
mkdir C:\VTS 2> NUL

utwórz folder o nazwie VTSi wyślij go A subdirectory or file TEST already existsdo NUL.

lub

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

zmień literę dysku na C:, mkdirbłąd wyjściowy na NULi uruchom następną komendę.

3 lata2late
źródło
Czy istnieje sposób, aby to działało w PowerShell? Wydaje się, że nie jest obsługiwany NULjako plik wyjściowy.
Aaron Franke
30
set myDIR=LOG
IF not exist %myDIR% (mkdir %myDIR%)
Robie
źródło
1
Jak zauważyli inni i być może widziałeś w najwyżej ocenianej odpowiedzi, nie działa to, jeśli masz plik o nazwie log. To subtelna różnica, ale doprowadzi do trudnych do znalezienia błędów w twoich skryptach.
Abel
20

Używam w ten sposób, powinieneś umieścić odwrotny ukośnik na końcu nazwy katalogu, aby uniknąć tego miejsca w pliku bez rozszerzenia o tej samej nazwie, co określony katalog, nigdy nie używaj „C: \ VTS”, ponieważ może to plik istnieje z nazwą „VTS” zapisaną na partycji „C:” , poprawnym sposobem jest użycie „C: \ VTS \” , sprawdź ukośnik odwrotny po VTS , więc jest to właściwy sposób.

@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
D3F4ULT
źródło
3
Szczególnie interesujące z twojego rozwiązania jest to, że używasz !errorlevel!, tj. Opóźnionej ekspansji. W przeciwnym razie zmienna ERRORLEVELbyłaby analizowana przed wprowadzeniem pierwszej if(tj. W czasie analizy). Teraz jest analizowany w czasie wykonywania, dzięki czemu może przechwycić wynik mkdir. Masz również rację, nawet jeśli testujesz na istnienie, powinieneś nadal testować na sukces (pomyśl: na przykład błąd odmowy dostępu). Bardzo dobre rozwiązanie w porównaniu do innych, +10 !!!
Abel
17

Możesz użyć:

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

Możesz także rozwinąć kod, aby zastąpić brakujące oczekiwane pliki.

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

źródło
0

stworzyłem to dla mojego skryptu, którego używam w mojej pracy dla oka.

: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\"
Winston
źródło