Câu trả lời:
Sử dụng Bash one-liner đơn giản này:
if [ -e FILENAME ] ; then echo Yes ; fi
Các -e
đánh giá lại séc là true nếu FILENAME
tồn tại, không có vấn đề gì nó là gì (tập tin, thư mục, liên kết, thiết bị, ...).
Nếu bạn chỉ muốn kiểm tra các tệp thông thường, hãy sử dụng -f
thay thế, như @Arronical đã nói.
FILENAME
là một mở rộng biến, hoặc chứa bất kỳ ký tự đặc biệt nào, thì đừng quên trích dẫn nó. ví dụ trong một kịch bản , [ -e "$1" ] && echo Yes
.
[[
và ]]
thay vì trích dẫn biến.
[[ ]]
, luôn luôn trích dẫn là một thói quen tốt cho người mới bắt đầu không nhớ các quy tắc đặc biệt cho bên trong [[ ]]
toán tử hoặc cho bối cảnh số học.
Bạn có thể sử dụng tập lệnh đơn giản này:
#!/bin/bash
if [[ -f $1 ]]; then
echo "Yes"
exit 0
else
exit 1
fi
Lưu nó như file-exists.sh
. Sau đó, trong Terminal, gõ chmod +x file-exists.sh
.
Sử dụng nó như: ./file-exists.sh FILE
nơi bạn thay thế FILE
bằng tệp bạn muốn kiểm tra, ví dụ:
./file-exists.sh file.txt
Nếu file.txt
tồn tại, Yes
sẽ được in ra Terminal và chương trình sẽ thoát với trạng thái 0 (thành công). Nếu tệp không tồn tại, sẽ không có gì được in và chương trình sẽ thoát với trạng thái 1 (thất bại).
Nếu bạn tò mò tại sao tôi lại đưa vào exit
lệnh, hãy đọc tiếp ...
exit
lệnh?exit
gây ra chấm dứt quá trình bình thường. Điều này có nghĩa là, về cơ bản: nó dừng tập lệnh. Nó chấp nhận một tham số (số) tùy chọn sẽ là trạng thái thoát của tập lệnh đã gọi nó.
Trạng thái thoát này cho phép các tập lệnh khác của bạn sử dụng file-exists
tập lệnh của bạn và là cách họ biết tệp có tồn tại hay không.
Một ví dụ đơn giản đặt cái này để sử dụng là tập lệnh này (lưu nó dưới dạng file-exists-cli.sh
):
#!/bin/bash
echo "Enter a filename and I will tell you if it exists or not: "
read FILE
# Run `file-exists.sh` but discard any output because we don't need it in this example
./file-exists.sh $FILE &>> /dev/null
# #? is a special variable that holds the exit status of the previous command
if [[ $? == 0 ]]; then
echo "$FILE exists"
else
echo "$FILE does not exist"
fi
Làm như bình thường chmod +x file-exists-cli.sh
và sau đó chạy nó : ./file-exists-cli.sh
. Bạn sẽ thấy một cái gì đó như thế này:
Tệp tồn tại ( exit 0
):
➜ ~ ./file-exists-cli.sh
Enter a filename and I will tell you if it exists or not:
booleans.py
booleans.py exists
Tệp không tồn tại ( exit 1
):
➜ ~ ./file-exists-cli.sh
Enter a filename and I will tell you if it exists or not:
asdf
asdf does not exist
"$1"
. Nếu nó có khoảng trắng trong đó, nó sẽ vỡ mà không có dấu ngoặc kép và những điều tồi tệ khác có thể xảy ra.
Trong bash shell trên dòng lệnh.
if [[ -f /path/to/file ]]; then echo "Yes"; fi
Điều này sử dụng toán tử điều kiện bash -f
và kiểm tra xem tệp có tồn tại và là một tệp thông thường hay không. Nếu bạn muốn kiểm tra bất kỳ tập tin bao gồm các thư mục và liên kết thì hãy sử dụng -e
.
test
ở định dạng ban đầu, tôi biết đó là quá mức cần thiết, nhưng đó là thói quen của tôi.
[
lệnh, thường gọi lệnh dựng sẵn.) Chúng sửa lỗi không nhất quán và hành vi ngu ngốc của phiên bản nẹp đơn. [Nội dung tích hợp vẫn còn để tương thích, nhưng tôi không thấy bất kỳ lý do chính đáng nào để sử dụng nó trong mã bash mới. (Nếu bạn cần viết các tập lệnh tuân thủ POSIX có thể chạy trên các shell cổ hoặc thứ gì đó, thì khác.)
[
thường gọi là dựng sẵn" là không rõ ràng. type -a [
đối với tôi liệt kê "shell dựng", sau đó " /usr/bin/[
."
type
Kết quả của bạn dường như chứng thực những gì tôi nói, phải không?
Lệnh ngắn nhất để làm những gì bạn muốn là:
test -e FILENAME && echo Yes
test -e
sẽ kiểm tra xem tên đã cho có tồn tại trong hệ thống tệp hay không. (Bạn chỉ có thể sử dụng test -f
để giới hạn các tệp thông thường. Xem man test
thêm.)
Nếu điều kiện đưa ra đánh giá là đúng, thì test
sẽ trả về trạng thái thoát thành công (nếu không, nó sẽ trả về trạng thái lỗi). Chúng tôi kết hợp hai lệnh bằng cách sử dụng &&
, có nghĩa là "thực hiện lệnh tiếp theo nếu lệnh trước đó thoát với trạng thái thành công". Lệnh tiếp theo chỉ đơn giản là in Yes
trên đầu ra tiêu chuẩn; trong trường hợp vỏ tương tác, trên thiết bị đầu cuối.
Điều này tránh các tài liệu văn bản bổ sung của một if
tuyên bố, nhưng cho kết quả tương tự. Sử dụng &&
(hoặc ngược lại, ||
) để liên kết các lệnh với nhau hoạt động tốt khi chỉ có một lệnh duy nhất được tham gia. Nếu bạn muốn làm nhiều hơn là thực thi một lệnh để đáp ứng với trạng thái thoát của một lệnh, thì việc sử dụng if
cú pháp nhanh chóng trở nên dễ đọc hơn nhiều.
Như đã chỉ ra trong các câu trả lời khác, if
cấu trúc kiểu tương đương sẽ là:
if test -e FILENAME; then echo Yes; fi
Hay cách khác:
if test -e FILENAME
then
echo Yes
fi
Đối với các mục đích này, [
và test
là tương đương, ngoại trừ [
yêu cầu chấm dứt ]
.
Để xử lý loại câu hỏi này có nhiều cách và đây là một cách khác: sử dụng find
lệnh với -exec
cờ. Đường dẫn đến tệp có thể được chia thành hai phần find /etc
đặt thư mục và -name FILENAME
chỉ định tên tệp (duh!). -maxdepth
sẽ chỉ tiếp tục find
làm việc với /etc
thư mục và sẽ không rơi vào thư mục con
adminx@L455D:~$ find /etc -maxdepth 1 -name passwd -exec printf "YES\n" \;
YES
adminx@L455D:~$ find /etc -maxdepth 1 -name passwd1 -exec printf "YES\n" \;
adminx@L455D:~$
Một cách khác, thông qua stat
:
adminx@L455D:~$ stat /etc/passwd1 &>/dev/null && echo YES
adminx@L455D:~$ stat /etc/passwd &>/dev/null && echo YES
YES
Và thay thế thông qua python:
>>> import os
>>> if os.stat('/etc/passwd'):
... print 'YES'
...
YES
>>> if os.stat('/etc/passwd1'):
... print 'YES'
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 2] No such file or directory: '/etc/passwd1'
Hoặc một dòng lệnh ngắn thay thế:
python -c "from os.path import exists; print 'Yes' if exists('/etc/fstab') else '' "
[ -e FILENAME ] && echo Yes