Kiểm tra sự tồn tại của nhiều thư mục


8

Tôi muốn kiểm tra sự tồn tại của nhiều thư mục, giả sử dir1, dir2dir3, trong thư mục làm việc.

Tôi có những điều sau đây

if [ -d "$PWD/dir1" ] && [ -d "$PWD/dir2" ] && [ -d "$PWD/dir3" ]; then
    echo True
else
    echo False
fi

Nhưng tôi nghi ngờ có một cách thanh lịch hơn để làm điều này. Đừng cho rằng có một mẫu trong tên của các thư mục.

Mục tiêu là để kiểm tra sự tồn tại của một vài thư mục và sự tồn tại của những thư mục khác.

Tôi đang sử dụng Bash, nhưng mã di động được ưa thích hơn.


1
Mục tiêu là để kiểm tra sự tồn tại của một vài thư mục và sự tồn tại của những thư mục khác. Vâng, ví dụ của bạn kiểm tra sự tồn tại của tất cả các thư mục được liệt kê. Bạn có thể giải thích về phần này? Có phải tất cả được liệt kê hoặc bất kỳ được liệt kê? Bạn có cần kiểm tra xem các giá trị đã qua có trong các thư mục thực tế không chứ không phải các loại tệp khác?
Sergiy Kolodyazhnyy

1
Nhân tiện, bạn không cần $PWD. [ -d "$PWD/dir1"]tương đương với [ -d "dir1" ].
terdon

Câu trả lời:


5

Nếu bạn đã mong đợi chúng là các thư mục và chỉ kiểm tra xem tất cả chúng có tồn tại hay không, bạn có thể sử dụng mã thoát khỏi lstiện ích để xác định xem có một hoặc nhiều "lỗi xảy ra" hay không :

ls "$PWD/dir1" "$PWD/dir2" "$PWD/dir3" >/dev/null 2>&1 && echo All there

Tôi chuyển hướng đầu ra và thiết bị lỗi chuẩn để /dev/nulllàm cho nó biến mất, vì chúng tôi chỉ quan tâm đến mã thoát ls, không phải đầu ra của nó. Bất cứ điều gì được viết để /dev/nullbiến mất - nó không được ghi vào thiết bị đầu cuối của bạn.


Bạn có thể giúp tôi hiểu lệnh này? Tôi biết những gì mô tả tập tin là. Tôi biết 1là stdout, 2là stderr và tôi biết chuyển hướng là gì. Tôi không hiểu tầm quan trọng của /dev/nullvà tôi không biết cách phân tích lệnh.
Elegance

@Elegance Tôi thêm một lời giải thích. Để biết thêm chiều sâu câu trả lời liên quan đến / dev / null, xem unix.stackexchange.com/questions/163352/...unix.stackexchange.com/questions/438130/...
Jeff Schaller

Vẫn đang cố gắng tìm ra cách cú pháp hoạt động. Tôi đọc rằng &>filenamechuyển hướng cả stdout và stderr đến filename. Vì vậy, lệnh không thể được đơn giản hóa (ít nhất là với tôi nó đơn giản hơn) như ls "$PWD/dir1" "$PWD/dir2" "$PWD/dir2" &>/dev/null && echo All there?
Elegance

3
(1) Có lẽ bạn nên sử dụng -dtùy chọn (a) vì vậy lschỉ cần thống kê các thư mục và không đọc chúng và (b) để lệnh sẽ thành công ngay cả khi người dùng không đọc quyền truy cập vào các thư mục. (2) Tôi không thấy bất kỳ lý do nào để sử dụng "$PWD/"ngoại trừ để bảo vệ chống lại các thư mục có tên bắt đầu -(và tất nhiên, có nhiều cách tốt hơn để làm điều đó).
G-Man nói 'Tái lập Monica'

1
lệnh này có thể mất nhiều thời gian hơn để chạy so với bài kiểm tra trong câu hỏi ban đầu. Ngoài ra, nó không kiểm tra các thư mục.
Jasen

9

Tôi sẽ lặp lại:

result=True
for dir in \
        "$PWD/dir1" \
        "$PWD/dir2" \
        "$PWD/dir3" 
do
    if ! [ -d "$dir" ]; then
        result=False
        break
    fi
done
echo "$result"

Các breaknguyên nhân gây vòng lặp để ngắn mạch, giống như chuỗi lại&&


5

Một vòng lặp có thể thanh lịch hơn:

arr=("$PWD/dir1" "$PWD/dir2" "$PWD/dir2")
for d in "${arr[@]}"; do
    if [ -d "$d"]; then
        echo True
    else
        echo False
    fi
done

Đây là Bash. Một thiết bị di động hơn là Sh. Ở đó bạn có thể sử dụng mảng vị trí:

set -- "$PWD/dir1" "$PWD/dir2" "$PWD/dir2"

Sau đó để lặp qua nó sử dụng "$@".


5

Tại sao không chỉ:

if [ -d "dir1" -a -d "dir2" -a -d "dir3" ]; then
    echo True
else
    echo False
fi

Đây thực chất là những gì OP bắt đầu,But I suspect there is a more elegant way of doing this
Jeff Schaller

5
Ngoài ra POSIX không khuyến khích việc sử dụng -a: " -a-ocác toán tử gốc nhị phân (...) đã bị đánh dấu lỗi thời": pubs.opengroup.org/onlinepub/9699919799
Elegance

@JeffSchaller Thật tuyệt vời hơn vì nó thực hiện tất cả trong một cuộc gọi để kiểm tra.
David Conrad

2
hoàn toàn không giống nhau, các lệnh gọi ban đầu test(hay còn gọi là [ba lần) gọi nó một lần,
Jasen

1
pubs.opengroup.org/onlinepub/9699919799/utilities/ vào là một tài liệu tham khảo chính xác hơn về vị trí của câu lệnh POSIX.
G-Man nói 'Tái lập Monica'

4

Theo câu hỏi, hai hàm shell di động kiểm tra sự tồn tại và không tồn tại của nhiều thư mục:

# Returns success if all given arguments exists and are directories.
ck_dir_exists () {
    for dir do
        [ -d "$dir" ] || return 1
    done
}

# Returns success if none of the given arguments are existing directories.
ck_dir_notexists () {
    for dir do
        [ ! -d "$dir" ] || return 1
    done
}

Thí dụ:

$ mkdir dir1 dir2
$ ck_dir_exists dir1 dir2; echo $?
0
$ ck_dir_exists dir1 dir2 dir3; echo $?
1
$ ck_dir_notexists dir1 dir2 dir3; echo $?
1
$ ck_dir_notexists dir3 dir4; echo $?
0

1

Mục tiêu là để kiểm tra sự tồn tại của một vài thư mục và sự tồn tại của những thư mục khác.   [Nhấn mạnh thêm]

Dựa trên câu trả lời của glenn jackman , chúng ta có thể kiểm tra sự tồn tại của các tên khác như thế này:

kết quả = đúng
cho dir trong \
        "$ PWD / dir1" \
        "$ PWD / dir2" \
        "$ PWD / dir3" 
làm
    nếu ! [-d "$ dir"]; sau đó
        kết quả = sai
        phá vỡ
    fi
làm xong
cho dir trong \
        "$ PWD / dir4" \
        "$ PWD / dir5" \
        "$ PWD / dir6" 
làm
    nếu [-e "$ dir"]; sau đó # Lưu ý: không có!
        kết quả = sai
        phá vỡ
    fi
thực hiện 
tiếng vang "$ result"
Tôi đã sử dụng [ -e "$dir" ]để kiểm tra xem có "$dir"tồn tại hay không ; tức là, nếu dir5tồn tại nhưng là một tập tin, kết quả là False. Nếu bạn chỉ muốn kiểm tra xem tên trong nhóm thứ hai có phải là thư mục hay không, hãy sử dụng [ -d "$dir" ], như trong vòng lặp đầu tiên.

Vì chúng ta đang nói về việc kiểm tra sự tồn tại của những thứ trong thư mục làm việc hiện tại, có lẽ không cần thiết phải chỉ định $PWD/tên; cứ làm đi

cho dir trong \
        "dir1" \
        "dir2" \
        "dir3" 
làm
      ︙

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.