Tạo thư mục với lô nhưng chỉ khi nó không tồn tại


440

Ai đó có thể cho tôi biết làm thế nào để thực hiện các thao tác sau trong tập lệnh bó Windows không? ( *.bat):

  • Chỉ tạo một thư mục nếu nó không tồn tại

Chi tiết hơn, tôi muốn tạo một thư mục có tên VTStrên C:\ổ đĩa, nhưng chỉ khi thư mục đó không tồn tại. Tôi không muốn ghi đè lên nội dung của thư mục nếu nó đã tồn tại và lô được thực thi.


2
Còn cái này thì sao ? if not exist "%Folder%" mkdir "%New-Folder%"
nhà khoa

Câu trả lời:


622

Bạn chỉ cần sử dụng cái này: if not exist "C:\VTS\" mkdir C:\VTSnó sẽ tạo một thư mục chỉ khi thư mục không tồn tại.

Lưu ý rằng kiểm tra sự tồn tại này sẽ trả về đúng chỉ khi VTS tồn tại và là một thư mục. Nếu nó không ở đó hoặc ở đó dưới dạng tệp, lệnh mkdir sẽ chạy và sẽ gây ra lỗi. Bạn có thể muốn kiểm tra xem VTS có tồn tại dưới dạng tệp không.


7
Ngoại trừ việc nó sai. Bạn phải kiểm tra thiết bị NUL, nếu không thiết bị sẽ không hoạt động. Xem câu trả lời của tôi sớm hơn ba năm so với câu hỏi này.
Martin Schapendonk

@MartinSchapendonk Điều này hoạt động trên Windows 7 và Windows Server 2012 theo như tôi có thể biết khi thử nghiệm, và tôi rất ngạc nhiên nếu nó không hoạt động ít nhất trở lại XP và lên Windows 10. Bạn có thể cung cấp các điều kiện khi cái này không hoạt động?
jpmc26

12
Kiểm tra @ jpmc26 cho NUL là để đảm bảo bạn kiểm tra thư mục. Nếu không, điều kiện có thể đánh giá là đúng, thậm chí nó là một tệp thông thường. Đó là sự khác biệt.
Martin Schapendonk

3
@MartinSchapendonk Việc thêm dấu gạch chéo có đủ cho điều đó không? Điều đó dường như để phân biệt chính xác giữa các tệp và thư mục, nhưng có một điểm yếu ở chỗ nếu tệp không được phát hiện, việc tạo thư mục sẽ thất bại. Tôi nghi ngờ đây cũng là một vấn đề với việc thử nghiệm NUL.
jpmc26

6
@ jpmc26 Bạn đã đúng, một dấu gạch chéo thực hiện công việc và thực sự thích hợp hơn vì nó hoạt động với dấu ngoặc kép (do đó cho phép bạn có khoảng trắng trong đường dẫn thư mục). Để phân biệt giữa một trong hai tập tin / thư mục, điều này sẽ làm việc : if exist "a" if not exist "a\" (echo "it's a file") else (echo "it's a dir"). Về câu cuối cùng của bạn, tôi nghi ngờ có gì đó không đúng với tệp bó của bạn ở nơi khác.
Marc.2377

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

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

Xem thêm https://support.microsoft.com/en-us/kb/65994

(Cập nhật ngày 7 tháng 3 năm 2018; Bài viết của Microsoft không hoạt động, lưu trữ trên https://web.archive.org/web/20150609092521/https://support.microsoft.com/en-us/kb/65994 )


12
Cá nhân tôi thích điều này vì nó không đặt% errorlevel% khi thư mục đã tồn tại (câu trả lời của Agent_9191 trả về mã lỗi là 1)
csauve

1
Nó cũng hay và chung chung và có thể được áp dụng cho mọi hành động khác mà bạn muốn thực hiện một cách có điều kiện :)
John Humphreys - w00te

3
@YouHaveaBigEgo đi NULcùng với một L.
Martin Schapendonk

1
Liên kết không còn hoạt động, nhưng có một bản sao tại Lưu trữ Internet
fernio

3
Trên thực tế, mặc dù câu trả lời này rất hay, nhưng nó không trả lời cho câu hỏi "tạo thư mục" :)
Jean-Francois T.

55

Chỉ cần gọi mkdir C:\VTSkhông có vấn đề gì. Nó chỉ đơn giản là báo cáo rằng thư mục con đã tồn tại.

Chỉnh sửa: Như những người khác đã lưu ý, điều này không đặt% ERRORLEVEL% nếu thư mục đã tồn tại. Nếu lô của bạn (hoặc bất kỳ quy trình nào gọi nó) không quan tâm đến mức độ lỗi, phương pháp này hoạt động tốt. Vì câu hỏi không đề cập đến việc tránh mức độ lỗi, câu trả lời này là hoàn toàn hợp lệ. Nó đáp ứng nhu cầu tạo thư mục nếu nó không tồn tại và nó không ghi đè lên nội dung của thư mục hiện có. Nếu không, hãy làm theo câu trả lời của Martin Schapendonk .


20
đây là hành vi xấu do thông báo / cảnh báo lỗi không mong muốn.
Nghiêm túc

10
Gọi một cái gì đó "hoàn toàn hợp lệ" khi nó vi phạm các thực tiễn tốt nhất là không trung thực về mặt trí tuệ. Một ví dụ khác: Khi ai đó hỏi bạn cách tránh một vấn đề bảo mật cụ thể nào đó, câu trả lời của bạn không nên là "chạy máy tính với tư cách quản trị viên" ngay cả khi câu hỏi không chỉ định rõ ràng tác động bảo mật tối thiểu là điều kiện tiên quyết. :-)
Jouni Heikniemi

2
@JouniHeikniemi s / thực hành tốt nhất / sở thích cá nhân của Jouni
dss539

4
Không có gì sai với Errorlevel hoặc errno. Chúng là các mô hình thông báo lỗi dành riêng cho nền tảng và chúng hoạt động cho mục đích mà chúng được xây dựng cho. Nhưng bất kể nền tảng hoặc cách tiếp cận nhắn tin là gì, tôi sẽ không đề xuất mô hình "thử làm điều này và khôi phục nếu nó thất bại" khi bạn có thể dễ dàng tránh - và do đó là tài liệu rõ ràng - trường hợp lỗi phổ biến. Do đó, tôi thấy cách tiếp cận kiểu "nếu không tồn tại" vượt trội. Nhưng, tôi không muốn hoặc không quan tâm quá nhiều đến một cuộc tranh luận về sự hình thành các thực tiễn tốt nhất. Tôi không có ý định xúc phạm bất cứ ai, chỉ muốn làm rõ downvote của tôi.
Jouni Heikniemi

4
Vấn đề đơn giản là bỏ qua lỗi là bạn không biết tại sao nó lại thất bại. Nó có thể thất bại vì thư mục đã tồn tại, vì người dùng không có quyền trên thư mục đó, vì đường dẫn cha không tồn tại hoặc do đĩa bị lỗi. "Tạo nếu nó không tồn tại" sẽ thất bại trong mọi trường hợp ngoại trừ trường hợp đầu tiên. Câu trả lời này dẫn đến một lỗi trong tất cả các trường hợp, mặc dù. Đó là lý do tại sao nó không phù hợp với tập lệnh bó. -1
jpmc26

38
mkdir C:\VTS 2> NUL

tạo ra một thư mục có tên VTSvà đầu ra A subdirectory or file TEST already existsđể NUL.

hoặc là

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

thay đổi ký tự ổ đĩa thành C:, mkdirlỗi đầu ra thành NULvà chạy lệnh tiếp theo.


Có cách nào để thực hiện công việc này trong PowerShell không? Nó dường như không hỗ trợ NULnhư một tập tin đầu ra.
Aaron Franke

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

1
Như những người khác đã chỉ ra và bạn có thể đã thấy trong câu trả lời được xếp hạng hàng đầu, điều này không hoạt động nếu bạn có một tệp có tên log. Đó là một sự khác biệt tinh tế, nhưng nó sẽ dẫn đến các lỗi khó tìm trong tập lệnh của bạn.
Abel

20

Tôi sử dụng cách này, bạn nên đặt dấu gạch chéo ngược ở cuối tên thư mục để tránh chỗ đó tồn tại trong tệp không có phần mở rộng có cùng tên với thư mục bạn đã chỉ định, không bao giờ sử dụng "C: \ VTS" vì nó có thể là tệp tồn tại với tên "VTS" được lưu trong phân vùng "C:" , cách chính xác là sử dụng "C: \ VTS \" , kiểm tra dấu gạch chéo ngược sau VTS , như vậy là đúng cách.

@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
Điều đặc biệt thú vị của giải pháp của bạn là bạn sử dụng !errorlevel!, tức là mở rộng bị trì hoãn. Nếu không, biến ERRORLEVELsẽ được phân tích cú pháp trước khi nhập đầu tiên if(nghĩa là tại thời điểm phân tích cú pháp). Bây giờ nó được phân tích cú pháp tại thời điểm thực hiện, vì vậy nó có thể nắm bắt kết quả của mkdir. Bạn cũng đúng ở chỗ, mặc dù bạn kiểm tra sự tồn tại, bạn vẫn nên kiểm tra sự thành công (ví dụ: lỗi truy cập bị từ chối chẳng hạn). Giải pháp rất tốt so với những người khác, +10 !!!
Abel

17

Bạn có thể dùng:

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

Bạn cũng có thể mở rộng mã để thay thế bất kỳ tập tin dự kiến ​​bị thiếu.

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

0

tôi đã tạo cái này cho kịch bản của mình, tôi sử dụng trong công việc của mình cho nhãn cầu.

: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\"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.