Làm thế nào để mkdir chỉ khi một dir chưa tồn tại?


1987

Tôi đang viết một kịch bản shell để chạy theo KornShell (ksh) trên AIX. Tôi muốn sử dụng mkdirlệnh để tạo một thư mục. Nhưng thư mục có thể đã tồn tại, trong trường hợp đó tôi không muốn làm gì cả. Vì vậy, tôi muốn kiểm tra xem thư mục không tồn tại hay loại bỏ lỗi "Tệp tồn tại" xuất hiện mkdirkhi nó cố gắng tạo thư mục hiện có.

Bất kỳ suy nghĩ về cách tốt nhất để làm điều này?

Câu trả lời:


3294

Hãy thử mkdir -p:

mkdir -p foo

Lưu ý rằng điều này cũng sẽ tạo ra bất kỳ thư mục trung gian không tồn tại; ví dụ,

mkdir -p foo/bar/baz

sẽ tạo ra các thư mục foo, foo/barfoo/bar/baznếu họ không tồn tại.

Một số triển khai như GNU mkdirbao gồm mkdir --parentsnhư một bí danh dễ đọc hơn, nhưng điều này không được chỉ định trong Đặc tả kỹ thuật POSIX / Single Unix và không có sẵn trên nhiều nền tảng phổ biến như macOS, BSD khác nhau và các Unix thương mại khác nhau, vì vậy cần tránh.

Nếu bạn muốn có lỗi khi thư mục mẹ không tồn tại và muốn tạo thư mục nếu nó không tồn tại, thì bạn có thể testcho sự tồn tại của thư mục trước:

[ -d foo ] || mkdir foo

11
ví dụ rút gọn bạn sử dụng là chính xác những gì bạn không nên làm. Nó đang đảo ngược logic để tiết kiệm không gian mã hóa nhưng nó nên sử dụng! và && và có ý nghĩa hơn đối với những người đọc nó.
Mike Q

16
@AndreasLarsen Câu hỏi này là về mkdircác hệ thống giống như Unix, không phải trên Windows. -plà bắt buộc để tuân thủ POSIX / Single Unix Đặc điểm kỹ thuật, do đó, bất cứ điều gì có ý định tuân thủ các thông số kỹ thuật đó sẽ hỗ trợ -p. Windows hoàn toàn khác, trừ khi bạn sử dụng lớp mô phỏng POSIX như Cygwin hoặc MSYS.
Brian Campbell

22
Tôi phát hiện ra một điều thú vị ngày hôm nay với mkdir -p, bạn có thể sử dụng dấu ngoặc! {}để tạo cây thư mục "phức tạp" trong một lệnh. Xem tại đây: technosophos.com/2010/04/15/15
herve

12
@MikeQ Tôi thích ||thay &&vì vì toàn bộ dòng có trạng thái thoát đúng. Quan trọng nếu shell của bạn chạy với errexithoặc nếu dòng đó là dòng cuối cùng trong hàm, trường hợp chuyển đổi, bất cứ điều gì.
rudimeier

9
@herve Điều đó không có gì để làm với mkdir; shell mở rộng một biểu thức như vậy thành một danh sách đối số rời rạc được truyền vào mkdir.
chepner

176

Điều này sẽ làm việc:

$ mkdir -p dir

hoặc là:

if [[ ! -e $dir ]]; then
    mkdir $dir
elif [[ ! -d $dir ]]; then
    echo "$dir already exists but is not a directory" 1>&2
fi

sẽ tạo thư mục nếu nó không tồn tại, nhưng cảnh báo bạn nếu tên của thư mục bạn đang cố tạo đã được sử dụng bởi một thứ khác ngoài thư mục.


Tôi không nghĩ rằng có một toán tử -d trong korn, thay vì -e được sử dụng cho cả các tệp / thư mục và chỉ kiểm tra sự tồn tại. Ngoài ra, tất cả đều trả về 0 khi thành công, vì vậy! là dư thừa. Sửa tôi nếu tôi sai.
kiềm

1
sai cả hai tính, AFAIK. các thử nghiệm trở lại đúng khi thành công và -d cũng tồn tại (ít nhất là trên MacOS X)
Alnitak

5
điều đáng nói là nó không an toàn cho chủ đề. giữa thời gian bạn kiểm tra xem thư mục có tồn tại và thời gian bạn cố gắng viết không, mọi thứ có thể thay đổi.
Justin L.


73

Xác định cây thư mục phức tạp bằng một lệnh

mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}

không có lỗi nếu tồn tại, tạo thư mục mẹ khi cần
Fedir RYKHTIK

18
Hãy nhớ rằng đây không phải là một tính năng của mkdirchính nó, mà là trình bao thực thi lệnh. Nó được gọi là mở rộng cú đúp - AFAIK, chỉ Bash, ksh, zsh và shell C hỗ trợ nó.
Daniel Kamil Kozar

3
nếu bạn có khoảng trắng xung quanh dấu phẩy, bạn có thể (sẽ) nhận được kết quả không mong muốn. Coi chừng.
Atlas7

1
@ Atlas7 đã nêu, bạn sẽ cần phải thoát các ký tự thường là một phần của regex. (tức là thay vì sử dụng folder namebạn cần sử dụng folder\ name)
John Hamilton

1
Đây không phải là một câu trả lời; đây là một chủ đề riêng biệt sẽ phù hợp hơn khi bình luận.
Chris Trang

40

Nếu bạn không muốn hiển thị bất kỳ thông báo lỗi:

[ -d newdir ] || mkdir newdir

Nếu bạn muốn hiển thị thông báo lỗi của riêng bạn:

[ -d newdir ] && echo "Directory Exists" || mkdir newdir

20

Người cũ đã cố gắng và sự thật

mkdir /tmp/qq >/dev/null 2>&1

sẽ làm những gì bạn muốn mà không có điều kiện cuộc đua nào mà nhiều giải pháp khác có.

Đôi khi các giải pháp đơn giản nhất (và xấu nhất) là tốt nhất.


5
Điều này sẽ thất bại nếu "tmp" không tồn tại. Nó cũng không cung cấp cho bạn bất kỳ xác nhận.
Mike Q

15

mkdir foohoạt động ngay cả khi thư mục tồn tại. Để làm cho nó chỉ hoạt động nếu thư mục có tên "foo" không tồn tại, hãy thử sử dụng -pcờ.

Thí dụ :-

mkdir -p foo

Điều này sẽ tạo thư mục có tên "foo" chỉ khi nó không tồn tại. :)


2
Như được đề cập bởi @BrianCampbell, điều này cũng sẽ tạo ra bất kỳ thư mục nào khác trong đường dẫn. Điều này có thể nguy hiểm nếu ví dụ một âm lượng trở nên không đếm được, vì nó có thể tạo các thư mục trong điểm gắn kết.
uliwitness

11
directory_name = "foo"

if [ -d $directory_name ]
then
    echo "Directory already exists"
else
    mkdir $directory_name
fi

10

Hoặc nếu bạn muốn kiểm tra sự tồn tại trước:

if [[ ! -e /path/to/newdir ]]; then
            mkdir /path/to/newdir
fi

-e là thử nghiệm tồn tại cho vỏ korn.

Bạn cũng có thể thử googling một hướng dẫn sử dụng vỏ korn.


10

mkdir không hỗ trợ chuyển đổi -p nữa trên các hệ thống Windows 8+.

Bạn có thể sử dụng điều này:

IF NOT EXIST dir_name MKDIR dir_name

10
OP đã nói về AIX kornshell ... không liên quan gì đến Windows, phải không?
J. Chomel

9

Tham khảo trang man man mkdircho tùy chọn -p

   -p, --parents
          no error if existing, make parent directories as needed

sẽ tạo ra tất cả các thư mục trong một đường dẫn nhất định, nếu tồn tại sẽ không có lỗi nếu không nó sẽ tạo ra tất cả các thư mục từ trái sang phải trong đường dẫn đã cho. Hãy thử lệnh dưới đây. các thư mục newdiranotherdirkhông tồn tại trước khi ban hành lệnh này

Cách sử dụng đúng

mkdir -p /tmp/newdir/anotherdir

Sau khi thực hiện lệnh, bạn có thể thấy newdiranotherdirtạo dưới / tmp. Bạn có thể đưa ra lệnh này bao nhiêu lần bạn muốn, lệnh luôn có exit(0). Vì lý do này, hầu hết mọi người sử dụng lệnh này trong shell script trước khi sử dụng các đường dẫn thực tế đó.


8

Bạn có thể sử dụng vòng lặp if để kiểm tra xem thư mục có tồn tại hay không, nếu nó không thoát ra ngoài việc tạo thư mục.

1) dir = / nhà / dir_name

if [ ! -d $dir ]
then
     mkdir $dir
else
     echo "Directory exists"  
fi

2) Bạn có thể thư mục sử dụng mkdir với tùy chọn -p để tạo thư mục. Nó sẽ kiểm tra nếu thư mục không có sẵn nó sẽ.

mkdir -p $dir

mkdir -p cũng cho phép tạo cấu trúc cây của thư mục. Nếu bạn muốn tạo thư mục mẹ và thư mục con bằng cách sử dụng cùng một lệnh, có thể chọn mkdir -p

mkdir -p /home/parent_dir /home/parent_dir/child1 /home/parent_dir/child2

Có bất kỳ lợi thế trong việc sử dụng if loop!? Tại sao ai đó chọn tùy chọn overp đó?!
pedram bashiri

1
Tôi đã chia sẻ cho bạn các cách tạo thư mục khi thư mục không tồn tại. Nó phụ thuộc vào yêu cầu trên một. Nếu bạn có một trường hợp sử dụng mà bạn cần kiểm tra xem thư mục không tồn tại và bạn muốn theo dõi điều đó để bạn có thể đi với giải pháp 1. Nếu không thành vấn đề, bạn có thể đi với giải pháp 2, nó sẽ tạo thư mục nếu không tồn tại
AbhinavVaidya8

Tôi đã không nhìn thấy một vòng lặp.
Amit N Nikol

3

Đây là một hàm đơn giản (bash shell) cho phép bạn tạo một thư mục nếu nó không tồn tại.

#----------------------------------
# Create a directory if it doesn't exist
#------------------------------------
createDirectory() {
    if [ ! -d $1 ]
        then
        mkdir -p $1
    fi
}

Bạn có thể gọi hàm trên là:

createdDirectory / tmp / fooDir / BarDir

Ở trên tạo ra fooDir và BarDir nếu chúng không tồn tại. Lưu ý tùy chọn "-p" trong lệnh mkdir tạo thư mục theo cách đệ quy. Hi vọng điêu nay co ich.


2
mkdir -p sam
  • mkdir = Tạo thư mục
  • -p = -
  • (không có lỗi nếu có, tạo thư mục mẹ khi cần)

2
if [ !-d $dirName ];then
     if ! mkdir $dirName; then  # Shorter version. Shell will complain if you put braces here though
     echo "Can't make dir: $dirName"
     fi
fi
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.