Làm cách nào để kiểm tra xem một thư mục có tồn tại trong tập lệnh shell Bash không?


3723

Lệnh nào có thể được sử dụng để kiểm tra xem một thư mục có tồn tại hay không, trong tập lệnh shell Bash?

Câu trả lời:


5150

Để kiểm tra xem một thư mục có tồn tại trong tập lệnh shell hay không, bạn có thể sử dụng như sau:

if [ -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY exists.
fi

Hoặc để kiểm tra xem một thư mục không tồn tại:

if [ ! -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY doesn't exist.
fi

Tuy nhiên, như Jon Ericson chỉ ra, các lệnh tiếp theo có thể không hoạt động như dự định nếu bạn không tính đến việc một liên kết tượng trưng đến một thư mục cũng sẽ vượt qua kiểm tra này. Ví dụ: chạy này:

ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then 
  rmdir "$SYMLINK" 
fi

Sẽ tạo thông báo lỗi:

rmdir: failed to remove `symlink': Not a directory

Vì vậy, các liên kết tượng trưng có thể phải được xử lý khác nhau, nếu các lệnh tiếp theo mong đợi các thư mục:

if [ -d "$LINK_OR_DIR" ]; then 
  if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here.
    rm "$LINK_OR_DIR"
  else
    # It's a directory!
    # Directory command goes here.
    rmdir "$LINK_OR_DIR"
  fi
fi

Lưu ý đặc biệt về dấu ngoặc kép được sử dụng để bọc các biến. Lý do cho điều này được giải thích bởi 8jean trong một câu trả lời khác .

Nếu các biến chứa khoảng trắng hoặc các ký tự bất thường khác, nó có thể sẽ khiến tập lệnh bị lỗi.


29
Nếu bạn muốn chơi nó an toàn với các công cụ GNU, việc sử dụng --rất được khuyến khích (điểm đánh dấu kết thúc tùy chọn). Mặt khác, nếu biến của bạn chứa thứ gì đó trông giống như một tùy chọn, tập lệnh sẽ thất bại giống như với khoảng trắng.
Marc Mutz - mmutz

2
Đối với các phiên bản hiện đại của bash, ksh, v.v ... [...] là bản dựng sẵn
fpmurphy

79
Một điều cần lưu ý: [ ! -d "$DIRECTORY" ]sẽ là sự thật, hoặc nếu $DIRECTORYkhông tồn tại, hoặc nếu không tồn tại nhưng không phải là một thư mục. Hãy xem xét một cái gì đó như if [ ! -d "$DIRECTORY" ] ; then mkdir "$DIRECTORY" ; fi; Điều này sẽ thất bại nếu "$DIRECTORY"là một tập tin. (Tất nhiên bạn nên kiểm tra xem dù mkdirthành công hay không; có một số lý do khiến nó có thể thất bại.)
Keith Thompson

5
Điều đáng nói là ngay khi kiểm tra được thực hiện, tình huống có thể đã thay đổi do các quy trình khác. Trong nhiều trường hợp, tốt hơn là chỉ tạo hoặc sử dụng thư mục và phản ứng khi thất bại.
Alfe

12
Thay vì kiểm tra cả thư mục ( -d) và symlink ( -L), việc thêm một dấu gạch chéo vào biến, sẽ dễ dàng hơn if [ -d "${THING:+$THING/}" ]. Một thư mục sẽ không quan tâm đến dấu gạch chéo. Một tập tin sẽ đánh giá thành sai. Trống sẽ vẫn trống, rất sai. Và một symlink sẽ được giải quyết đến đích của nó. Tất nhiên, nó phụ thuộc vào mục tiêu của bạn. Nếu bạn muốn đi ở đó, điều này là tốt. Nếu bạn muốn xóa nó , thì mã trong câu trả lời này là tốt hơn.
ghoti

531

Hãy nhớ luôn luôn bọc các biến trong dấu ngoặc kép khi tham chiếu chúng trong tập lệnh Bash. Trẻ em ngày nay lớn lên với ý tưởng rằng chúng có thể có không gian và rất nhiều nhân vật ngộ nghĩnh khác trong tên thư mục của chúng. (Không gian! Quay lại thời của tôi, chúng tôi đã không có không gian ưa thích !;))

Một ngày nào đó, một trong những đứa trẻ đó sẽ chạy tập lệnh của bạn với $DIRECTORYcài đặt "My M0viez"và tập lệnh của bạn sẽ nổ tung. Bạn không muốn điều đó. Vì vậy, sử dụng này.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi

9
Một lý do khác để sử dụng dấu ngoặc kép là trong trường hợp $ DIRECTORY không được đặt vì một số lý do.
Jon Ericson

2
"luôn luôn bọc các biến trong dấu ngoặc kép ... trong tập lệnh bash." Đối với bash, không cần thiết về mặt kỹ thuật khi sử dụng [[...]]; xem tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS (lưu ý: không tách từ): "Không mở rộng tên tệp hoặc tách từ diễn ra giữa [[và]], nhưng có mở rộng tham số và thay thế lệnh."
michael

2
Các thư mục trên Unix / Linux không nên có bất kỳ khoảng trắng nào và các tập lệnh sau đó không được điều chỉnh cho phù hợp. Nó đủ tệ để Windows hỗ trợ nó, với tất cả các hậu quả đối với kịch bản Windows, nhưng xin vui lòng, vì tình yêu của bất cứ điều gì, không cần phải đưa ra các yêu cầu không cần thiết.
tvCa

18
@tvCa Tôi thấy rằng người dùng thường thích được phép linh hoạt hơn trong tên thư mục của mình hơn là bị buộc phải làm cho mọi thứ dễ dàng hơn cho các nhà phát triển. (Trên thực tế, khi xử lý các tên tệp dài, tôi thấy các tên không có khoảng trắng là một nỗi đau vì nó giết chết gói từ mặc dù bản thân tôi đã phải chịu đựng trong quá khứ vì không tính toán các đường dẫn có khoảng trắng trong các tập lệnh và chương trình.)
JAB

2
Hà. Spaces chỉ là các ký tự không có glyphs thường. Dù sao, bạn có thể thoát khỏi chúng bằng dấu gạch chéo ngược.
uchuugaka

228

Lưu ý kiểm tra -d có thể tạo ra một số kết quả đáng ngạc nhiên:

$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory

Tập tin bên dưới: "Khi nào một thư mục không phải là một thư mục?" Câu trả lời: "Khi đó là một liên kết tượng trưng đến một thư mục." Một bài kiểm tra kỹ lưỡng hơn một chút:

if [ -d t ]; then 
   if [ -L t ]; then 
      rm t
   else 
      rmdir t
   fi
fi

Bạn có thể tìm thêm thông tin trong hướng dẫn Bash về các biểu thức điều kiện Bash[lệnh dựng sẵn và dấu [[phẩy ghép .


12
hoặc, giả sử chỉ cần làm việc trên các thư mục (và có thể bỏ qua các liên kết) => if [ -d tmpdir -a ! -L tmpdir ]; then echo "is directory"; rmdir tmpdir; fi... hoặc, đối với một lệnh hoạt động trên cả hai liên kết & thư mục:rm -r tmpdir
michael

218

Tôi thấy phiên bản khung đôitest giúp việc viết các bài kiểm tra logic trở nên tự nhiên hơn:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi

if [[ -d "$TARFILE" ]]tôi nhận được [[: không tìm thấy
TheVillageIdiot

15
@TheVillageIdiot và @Hedgehog, bạn có đang sử dụng bash shell không? Khung đôi không được hỗ trợ phổ biến. Đây là câu trả lời SO về điểm đó: stackoverflow.com/questions/669452/ từ
yukondude

6
Và trong Busybox ash với các tùy chọn biên dịch mặc định [[ ]]được hỗ trợ, nhưng trên thực tế không cung cấp bất kỳ chức năng nào khác [ ]. Nếu tính di động là một mối quan tâm, hãy gắn bó [ ]và sử dụng các cách giải quyết cần thiết.
dubiousjim

6
... nếu sử dụng các cấu trúc bash trong tập lệnh shell, dòng đầu tiên của tập lệnh sẽ là: #! / bin / bash (chứ không phải #! / bin / sh, ksh, v.v.)
michael

Khi sử dụng dấu ngoặc vuông trong bash, bạn không cần trích dẫn các biến.
Hubert Grzeskowiak

157

Mẫu ngắn hơn:

[ -d "$DIR" ] && echo "Yes"

6
Cái này có hoạt động như thế này if $dir is a dir, then echo "yes"không? Một chút giải thích sẽ giúp :)
Martijn

5
cmd && otherlà một cách viết tắt phổ biến cho if cmd; then other; fi- điều này hoạt động với hầu hết các ngôn ngữ lập trình hỗ trợ logic Boolean và được gọi là đánh giá ngắn mạch .
tripleee

1
Các hành vi không giống nhau dưới set -e(đó là một thực hành tốt nhất lập trình shell ).
heo

1
@dolmen the [ -d "$DIR" ]được kiểm tra (theo sau && echo Yes), vì vậy tôi tin rằng set -ekhông có sự khác biệt nào đối với hành vi tập lệnh (nghĩa là nếu thử nghiệm thất bại, tập lệnh tiếp tục bình thường).
tzot

132

Để kiểm tra xem một thư mục có tồn tại không, bạn có thể sử dụng một ifcấu trúc đơn giản như thế này:

if [ -d directory/path to a directory ] ; then
# Things to do

else #if needed #also: elif [new condition]
# Things to do
fi

Bạn cũng có thể làm điều đó trong phủ định:

if [ ! -d directory/path to a directory ] ; then
# Things to do when not an existing directory

Lưu ý : Cẩn thận. Để lại các khoảng trống ở hai bên của cả hai dấu ngoặc mở và đóng.

Với cùng một cú pháp bạn có thể sử dụng:

-e: any kind of archive

-f: file

-h: symbolic link

-r: readable file

-w: writable file

-x: executable file

-s: file size greater than zero

Làm thế nào là tốt hơn so với câu trả lời được chấp nhận từ năm 2008, ngoài việc lạc đề với các chuyển đổi tập tin?
Dan Dascalescu

tốt hơn, vì [! -d thư mục / đường dẫn đến một thư mục]
user1855805

108
  1. Một tập lệnh đơn giản để kiểm tra xem một thư mục hoặc tập tin có hay không:

    if [ -d /home/ram/dir ]   # For file "if [-f /home/rama/file]"
    then
        echo "dir present"
    else
        echo "dir not present"
    fi
  2. Một tập lệnh đơn giản để kiểm tra xem thư mục có mặt hay không:

    mkdir tempdir   # If you want to check file use touch instead of mkdir
    ret=$?
    if [ "$ret" == "0" ]
    then
        echo "dir present"
    else
        echo "dir not present"
    fi

    Các kịch bản trên sẽ kiểm tra xem thư mục có mặt hay không

    $? nếu lệnh cuối cùng thành công, nó sẽ trả về "0", nếu không thì giá trị khác không. Giả sử tempdirđã có mặt. Sau đó mkdir tempdirsẽ đưa ra một lỗi như dưới đây:

    mkdir: không thể tạo thư mục 'tempdir': Tệp tồn tại


4
Cái thứ hai sẽ tạo thư mục, nếu nó không tồn tại lúc đầu. Sau đó, nó không phải là idempotent.
Shihe Zhang

👆👆👆. Cái thứ 2 có vẻ nguy hiểm. Vì nó tạo thư mục, nên nó không còn đúng nữa khi thư mục không có mặt.
Chris

92

Bạn có thể sử dụng test -d(xem man test).

-d file Đúng nếu tập tin tồn tại và là một thư mục.

Ví dụ:

test -d "/etc" && echo Exists || echo Does not exist

Lưu ý: testLệnh này giống như biểu thức điều kiện [(xem man [:), vì vậy nó có thể di chuyển trên các tập lệnh shell.

[- Đây là một từ đồng nghĩa với testnội dung, nhưng đối số cuối cùng phải, theo nghĩa đen ], để phù hợp với phần mở đầu [.

Đối với các tùy chọn có thể hoặc trợ giúp thêm, hãy kiểm tra:

  • help [
  • help test
  • man test hoặc là man [

55

Hoặc cho một cái gì đó hoàn toàn vô dụng:

[ -d . ] || echo "No"

6
Nó sẽ không bao giờ in "Không". Thư mục hiện tại luôn tồn tại, trừ khi bị xóa bởi một luồng khác hoặc các cách khác.
Jahid

Mẫu hoàn hảo :) cho rằng mức độ "độc nhất" là một số câu trả lời so với câu trả lời được chấp nhận
Sergey Sargsyan

4
Tại sao điều này đã được nâng cấp rất nhiều lần? Nó không trả lời câu hỏi.
tiền mã hóa

VÌ NÓ LÀ BẤT CỨ ĐÁP ÁN TỐT NHẤT EVA
Karl Morrison

52

Đây là một thành ngữ rất thực dụng:

(cd $dir) || return # Is this a directory,
                    # and do we have access?

Tôi thường bọc nó trong một chức năng:

can_use_as_dir() {
    (cd ${1:?pathname expected}) || return
}

Hoặc là:

assert_dir_access() {
    (cd ${1:?pathname expected}) || exit
}

Điều hay ho về cách tiếp cận này là tôi không phải nghĩ đến một thông báo lỗi tốt.

cdsẽ cung cấp cho tôi một thông báo một dòng tiêu chuẩn cho lỗi tiêu chuẩn . Nó cũng sẽ cung cấp nhiều thông tin hơn tôi sẽ có thể cung cấp. Bằng cách thực hiện cdbên trong một lớp con ( ... ), lệnh không ảnh hưởng đến thư mục hiện tại của người gọi. Nếu thư mục tồn tại, lớp con này và hàm chỉ là một no-op.

Tiếp theo là đối số mà chúng ta chuyển đến cd: ${1:?pathname expected}. Đây là một hình thức thay thế tham số phức tạp hơn được giải thích chi tiết hơn dưới đây.

Tl; dr: Nếu chuỗi được truyền vào hàm này trống, chúng ta lại thoát khỏi lớp con ( ... )và trả về từ hàm với thông báo lỗi đã cho.


Trích dẫn từ ksh93trang người đàn ông:

${parameter:?word}

Nếu parameter được đặt và không null thì thay thế giá trị của nó; mặt khác, in wordvà thoát khỏi vỏ (nếu không tương tác). Nếu wordđược bỏ qua thì một thông điệp tiêu chuẩn được in.

Nếu dấu hai chấm :được bỏ qua trong các biểu thức trên, thì shell chỉ kiểm tra xem tham số có được đặt hay không.

Phrasing ở đây là đặc thù của tài liệu shell, vì wordcó thể đề cập đến bất kỳ chuỗi hợp lý nào, bao gồm cả khoảng trắng.

Trong trường hợp cụ thể này, tôi biết rằng thông báo lỗi tiêu chuẩn 1: parameter not setlà không đủ, vì vậy tôi phóng to loại giá trị mà chúng tôi mong đợi ở đây - pathnamecủa một thư mục.

Một ghi chú triết học:

Shell không phải là một ngôn ngữ hướng đối tượng, vì vậy thông báo nói pathname, không directory. Ở cấp độ này, tôi muốn giữ cho nó đơn giản - các đối số cho hàm chỉ là các chuỗi.


Điều này không chỉ kiểm tra sự tồn tại: Kiểm tra khả năng truy cập ở cấp độ người dùng của bạn. Câu hỏi SO chỉ tồn tại . Vì vậy, câu trả lời đúng là test -dnhư @Grundlefleck giải thích.
F. Hauri

7
@ F.Hauri - Anh ấy không yêu cầu gì thêm, đó là sự thật. Tuy nhiên, tôi thấy rằng tôi thường cần biết nhiều hơn thế.
Henk Langeveld

Và tôi chưa bao giờ nghĩ rằng không có kết luận nào có thể kết luận được, trừ khi nó chạy bằng root. test -d /unreadable/existssẽ thất bại, ngay cả khi đối số tồn tại.
Henk Langeveld

36
if [ -d "$Directory" -a -w "$Directory" ]
then
    #Statements
fi

Các mã trên kiểm tra nếu thư mục tồn tại và nếu nó có thể ghi.


1
-a giống hệt với hiệu ứng -e. Nó đã bị "không dùng nữa" và việc sử dụng nó không được khuyến khích.
CousinCocaine

27
DIRECTORY=/tmp

if [ -d "$DIRECTORY" ]; then
    echo "Exists"
fi

Thử trực tuyến


ghi nhớ spacesau [-> [`` -d . tôi đã gặp lỗi vì thiếu không gian
Raj

4
LẠI , câu trả lời này đã được đưa ra vào năm 2008, với những lời giải thích hữu ích hơn. Điều mới duy nhất ở đây là sân chơi trực tuyến.
Dan Dascalescu

24

Nhập mã này vào dấu nhắc Bash:

if [ -d "$DIRECTORY" ]; then
    # If true this block of code will execute
fi

LẠI , câu trả lời này đã được đưa ra vào năm 2008. Điểm nào trong việc lặp lại nó?!
Dan Dascalescu

21

Thêm tính năng sử dụng find

  • Kiểm tra sự tồn tại của thư mục trong các thư mục con:

    found=`find -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where "myDirectory" is.
        # It may contain several lines if there are several folders named "myDirectory".
    fi
  • Kiểm tra sự tồn tại của một hoặc một số thư mục dựa trên một mẫu trong thư mục hiện tại:

    found=`find -maxdepth 1 -type d -name "my*"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where folders "my*" have been found.
    fi
  • Cả hai kết hợp. Trong ví dụ sau, nó kiểm tra sự tồn tại của thư mục trong thư mục hiện tại:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi

Chào Niel. Ý tưởng của bạn có thể hữu ích để kiểm tra sự tồn tại của các thư mục tùy thuộc vào một mẫu như : find -maxdepth 1 -type d -name 'pattern'. Bạn có phiền nếu tôi nối vào câu trả lời của bạn không? Chúc mừng;)
olibre

20

Trên thực tế, bạn nên sử dụng một số công cụ để có được cách tiếp cận chống đạn:

DIR_PATH=`readlink -f "${the_stuff_you_test}"` # Get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; Then # Now you're testing
    echo "It's a dir";
fi

Không cần phải lo lắng về không gian và các ký tự đặc biệt miễn là bạn sử dụng "${}".

Lưu ý rằng [[]]nó không phải là di động như [], nhưng vì hầu hết mọi người làm việc với các phiên bản hiện đại của Bash (vì xét cho cùng, hầu hết mọi người thậm chí không làm việc với dòng lệnh :-p), lợi ích lớn hơn rắc rối.


17

Bạn đã xem xét chỉ làm bất cứ điều gì bạn muốn làm trong ifhơn là tìm kiếm trước khi bạn nhảy?

Tức là, nếu bạn muốn kiểm tra sự tồn tại của một thư mục trước khi bạn nhập nó, hãy thử làm điều này:

if pushd /path/you/want/to/enter; then
    # Commands you want to run in this directory
    popd
fi

Nếu đường dẫn bạn đưa ra để pushdtồn tại, bạn sẽ nhập nó và nó sẽ thoát theo 0, có nghĩa là thenphần của câu lệnh sẽ thực thi. Nếu nó không tồn tại, sẽ không có gì xảy ra (ngoài một số đầu ra nói rằng thư mục không tồn tại, đây có thể là một tác dụng phụ hữu ích để gỡ lỗi).

Có vẻ tốt hơn thế này, đòi hỏi phải lặp lại chính mình:

if [ -d /path/you/want/to/enter ]; then
    pushd /path/you/want/to/enter
    # Commands you want to run in this directory
    popd
fi

Điều tương tự cũng làm việc với cd, mv, rm, vv ... nếu bạn thử chúng trên các tập tin không tồn tại, họ sẽ thoát ra với một lỗi và in một thông báo nói rằng nó không tồn tại, và bạnthen khối sẽ bị bỏ qua. Nếu bạn thử chúng trên các tệp tồn tại, lệnh sẽ thực thi và thoát với trạng thái 0, cho phép thenkhối của bạn thực thi.


2
Pushd là với tôi cách thanh lịch nhất để làm điều này. Tôi chuẩn bị đăng nó như một câu trả lời :)
melMass

16
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

NB: Trích dẫn các biến là một thực hành tốt.

Giải trình:

  • -d: kiểm tra xem đó có phải là một thư mục không
  • -L: kiểm tra xem đó có phải là một liên kết tượng trưng không

Một lời giải thích sẽ theo thứ tự (bằng cách chỉnh sửa câu trả lời của bạn , không phải ở đây trong các bình luận).
Peter Mortensen

15

Để kiểm tra nhiều thư mục, hãy sử dụng mã này:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi

Làm thế nào bạn có thể kiểm tra xem nó không tồn tại?
perrohunter

15

Kiểm tra nếu thư mục tồn tại, khác làm cho một:

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY

16
Bạn có thể sử dụng mkdir -p "$DIRECTORY"cho cùng một hiệu ứng.
Pickup Logan


11

Câu trả lời này được gói gọn như một kịch bản shell

Ví dụ

$ is_dir ~                           
YES

$ is_dir /tmp                        
YES

$ is_dir ~/bin                       
YES

$ mkdir '/tmp/test me'

$ is_dir '/tmp/test me'
YES

$ is_dir /asdf/asdf                  
NO

# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
  echo "Folder doesnt exist: $DIR";
  exit;
fi

is_dir

function show_help()
{
  IT=$(CAT <<EOF

  usage: DIR
  output: YES or NO, depending on whether or not the directory exists.

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

DIR=$1
if [ -d $DIR ]; then 
   echo "YES";
   exit;
fi
echo "NO";

10

Sử dụng -ekiểm tra sẽ kiểm tra các tập tin và điều này bao gồm các thư mục.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi

1
Và không trả lời đúng câu hỏi của OP - nó có phải là một thư mục không?
Mark Stewart

8

Theo nhận xét của Jonathan :

Nếu bạn muốn tạo thư mục và nó chưa tồn tại, thì kỹ thuật đơn giản nhất là sử dụng mkdir -pđể tạo thư mục - và bất kỳ thư mục bị thiếu nào trên đường dẫn - và không thất bại nếu thư mục đã tồn tại, vì vậy bạn có thể làm tất cả cùng một lúc với:

mkdir -p /some/directory/you/want/to/exist || exit 1

7
if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

Điều này không hoàn toàn đúng...

Nếu bạn muốn vào thư mục đó, bạn cũng cần có quyền thực thi trên thư mục. Có lẽ bạn cần phải có quyền viết là tốt.

Vì thế:

if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
    # ... to go to that directory (even if DIRECTORY is a link)
    cd $DIRECTORY
    pwd
fi

if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
    # ... to go to that directory and write something there (even if DIRECTORY is a link)
    cd $DIRECTORY
    touch foobar
fi

7

Sử dụng filechương trình. Xem xét tất cả các thư mục cũng là các tệp trong Linux, ban hành lệnh sau sẽ đủ:

file $directory_name

Kiểm tra tệp không tồn tại: file blah

Đầu ra: cannot open 'blah' (No such file or directory)

Kiểm tra một thư mục hiện có: file bluh

Đầu ra: bluh: directory


1
Ý tưởng hay, tuy nhiên quá tệ trong cả hai trường hợp lệnh tập tin trả về 0 mã thoát luôn. Ngoài ra khi không thể tìm thấy tệp / thư mục :(.
risk89

6

Các lslệnh kết hợp với -l(dài niêm yết) trả về tùy chọn các thuộc tính thông tin về các tập tin và thư mục.
Cụ thể, ký tự đầu tiên của ls -lđầu ra, nó thường là a dhoặc -dấu gạch ngang. Trong trường hợp một dtrong những người được liệt kê là một thư mục chắc chắn.

Lệnh sau chỉ trong một dòng sẽ cho bạn biết nếu ISDIRbiến đã cho có chứa đường dẫn đến thư mục hay không:

[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
    echo "YES, $ISDIR is a directory." || 
    echo "Sorry, $ISDIR is not a directory"

Cách sử dụng thực tế:

    [claudio@nowhere ~]$ ISDIR="$HOME/Music" 
    [claudio@nowhere ~]$ ls -ld "$ISDIR"
    drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." ||
        echo "Sorry, $ISDIR is not a directory"
    YES, /home/claudio/Music is a directory.

    [claudio@nowhere ~]$ touch "empty file.txt"
    [claudio@nowhere ~]$ ISDIR="$HOME/empty file.txt" 
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." || 
        echo "Sorry, $ISDIR is not a directoy"
    Sorry, /home/claudio/empty file.txt is not a directory

+1, nhưng khi ISDIR hoàn toàn không tồn tại, bạn sẽ nhận được thông báo lỗi cũng như thông báo chẩn đoán.
ysap


5

Nếu bạn muốn kiểm tra xem một thư mục có tồn tại hay không, bất kể đó là thư mục thực hay liên kết tượng trưng, ​​hãy sử dụng:

ls $DIR
if [ $? != 0 ]; then
        echo "Directory $DIR already exists!"
        exit 1;
fi
echo "Directory $DIR does not exist..."

Giải thích: Lệnh "ls" đưa ra lỗi "ls: / x: Không có tệp hoặc thư mục như vậy" nếu thư mục hoặc symlink không tồn tại và cũng đặt mã trả về mà bạn có thể truy xuất thông qua "$?", Không -null (thường là "1"). Hãy chắc chắn rằng bạn kiểm tra mã trả lại trực tiếp sau khi gọi "ls".


3
Ngoài ra, bạn có thể sử dụng phiên bản ngắn hơn này:if ! ls $DIR 2>/dev/null; then echo "$DIR does not exist!"; fi
derFunk

5

(1)

[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"

(2)

[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"

(3)

[[ -d run_dir  && ! -L run_dir ]] && echo Exists || echo "Not Exists"

Nếu một vấn đề được tìm thấy với một trong những cách tiếp cận được cung cấp ở trên:

Với lsmệnh lệnh; các trường hợp khi một thư mục không tồn tại - một thông báo lỗi được hiển thị

[[ `ls -ld SAMPLE_DIR| grep ^d | wc -l` -eq 1 ]] && echo exists || not exists

-ksh: not: not find [Không có tập tin hoặc thư mục như vậy]


"Trên" đề cập đến điều gì? Ba dòng lệnh trong câu trả lời này hoặc câu trả lời trước? (Vui lòng trả lời bằng cách chỉnh sửa câu trả lời của bạn , không phải ở đây trong các bình luận. Cảm ơn trước.).
Peter Mortensen

4

Có những giải pháp tuyệt vời ngoài kia, nhưng cuối cùng mọi kịch bản sẽ thất bại nếu bạn không ở đúng thư mục. Mã như thế này:

if [ -d "$LINK_OR_DIR" ]; then
if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here
    rm "$LINK_OR_DIR"
else
    # It's a directory!
    # Directory command goes here
    rmdir "$LINK_OR_DIR"
fi
fi

sẽ chỉ thực hiện thành công nếu tại thời điểm thực thi bạn đang ở trong một thư mục có thư mục con mà bạn tình cờ kiểm tra.

Tôi hiểu câu hỏi ban đầu như thế này: để xác minh xem một thư mục có tồn tại không phân biệt vị trí của người dùng trong hệ thống tệp. Vì vậy, sử dụng lệnh 'find' có thể thực hiện thủ thuật:

dir=" "
echo "Input directory name to search for:"
read dir
find $HOME -name $dir -type d

Giải pháp này rất tốt vì nó cho phép sử dụng ký tự đại diện, một tính năng hữu ích khi tìm kiếm tệp / thư mục. Vấn đề duy nhất là, nếu thư mục được tìm kiếm không tồn tại, lệnh 'find' sẽ không in gì cho đầu ra tiêu chuẩn (không phải là một giải pháp tao nhã theo sở thích của tôi) và dù sao cũng sẽ có một lối thoát bằng không. Có lẽ ai đó có thể cải thiện điều này.


13
Tôi sẽ bị xúc phạm nếu một chương trình đã xem qua toàn bộ ổ cứng của tôi để tìm một thư mục thay vì chỉ nhìn một cách lịch sự trong thư mục làm việc hiện tại của tôi hoặc sử dụng đường dẫn tuyệt đối mà tôi đưa ra. Những gì bạn đã đề xuất có thể tốt cho một công cụ có tên locatenhưng không tốt cho bất kỳ thứ gì khác ...
sarnold
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.