[ -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 .txtvà 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.txtvà /b.txt, [sẽ được thông qua 5 đối số: [, -f, /a.txt, /b.txtvà ]. [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 *.txtmẫ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 nullgloblà bashcụ thể, nhưng vỏ thích ksh93, zsh, yash, tcshcó 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ư lshoặc stattrên danh sách các tệp được tính toán bởi trình bao.
shTươ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 *.txtmở rộng ra *.txt, bạn không biết liệu đó là vì không có .txttệp nào trong thư mục hay vì có một tệp được gọi *.txt. Sử dụng [*].txt *.txtcho 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.