[ -f /*.txt ]
sẽ chỉ trả về đúng nếu có một (và chỉ một) tệp không bị ẩn trong /
đó có tên kết thúc .txt
và nếu tệp đó là tệp thông thường hoặc liên kết tượng trưng đến tệp thông thường.
Đó là bởi vì các ký tự đại diện được mở rộng bằng vỏ trước khi được truyền cho lệnh (ở đây [
).
Vì vậy, nếu có một /a.txt
và /b.txt
, [
sẽ được thông qua 5 đối số: [
, -f
, /a.txt
, /b.txt
và ]
. [
sau đó sẽ phàn nàn rằng -f
được đưa ra quá nhiều đối số.
Nếu bạn muốn kiểm tra xem *.txt
mẫu có mở rộng thành ít nhất một tệp không bị ẩn (thường xuyên hay không):
shopt -s nullglob
set -- *.txt
if [ "$#" -gt 0 ]; then
./script "$@" # call script with that list of files.
fi
# Or with bash arrays so you can keep the arguments:
files=( *.txt )
# apply C-style boolean on member count
(( ${#files[@]} )) && ./script "${files[@]}"
shopt -s nullglob
là bash
cụ thể, nhưng vỏ thích ksh93
, zsh
, yash
, tcsh
có báo cáo tương đương.
Lưu ý rằng nó tìm thấy các tệp đó bằng cách đọc nội dung của thư mục, nó không thử và truy cập các tệp đó, điều này làm cho nó hiệu quả hơn các giải pháp gọi các lệnh như ls
hoặc stat
trên danh sách các tệp được tính toán bởi trình bao.
sh
Tương đương tiêu chuẩn sẽ là:
set -- [*].txt *.txt
case "$1$2" in
('[*].txt*.txt') ;;
(*) shift; script "$@"
esac
Vấn đề là với các vỏ Bourne hoặc POSIX, nếu một mẫu không khớp, nó sẽ tự mở rộng. Vì vậy, nếu *.txt
mở rộng ra *.txt
, bạn không biết liệu đó là vì không có .txt
tệp nào trong thư mục hay vì có một tệp được gọi *.txt
. Sử dụng [*].txt *.txt
cho phép phân biệt giữa hai.
/
? Ngoài ra, bạn đang thiếu một dấu chấm phẩy trước đófi
.