[ -f /*.txt ]
akan mengembalikan true hanya jika ada satu (dan hanya satu) file tidak tersembunyi /
yang namanya berakhir .txt
dan jika file itu adalah file biasa atau symlink ke file biasa.
Itu karena wildcard diperluas oleh shell sebelum diteruskan ke perintah (di sini [
).
Jadi jika ada /a.txt
dan /b.txt
, [
akan diteruskan 5 argumen: [
, -f
, /a.txt
, /b.txt
dan ]
. [
kemudian akan mengeluh karena -f
diberi terlalu banyak argumen.
Jika Anda ingin memeriksa apakah *.txt
polanya meluas ke setidaknya satu file yang tidak disembunyikan (biasa atau tidak):
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
adalah bash
spesifik, tapi kerang seperti ksh93
, zsh
, yash
, tcsh
memiliki pernyataan setara.
Perhatikan bahwa ia menemukan file-file itu dengan membaca konten direktori, itu tidak mencoba dan mengakses file-file itu sama sekali yang membuatnya lebih efisien daripada solusi yang memanggil perintah seperti ls
atau stat
pada daftar file yang dihitung oleh shell.
sh
Setara standar akan menjadi:
set -- [*].txt *.txt
case "$1$2" in
('[*].txt*.txt') ;;
(*) shift; script "$@"
esac
Masalahnya adalah bahwa dengan cangkang Bourne atau POSIX, jika suatu pola tidak cocok, itu mengembang sendiri. Jadi jika *.txt
diperluas *.txt
, Anda tidak tahu apakah itu karena tidak ada .txt
file di direktori atau karena ada satu file yang dipanggil *.txt
. Menggunakan [*].txt *.txt
memungkinkan untuk membedakan keduanya.
/
? Juga, Anda kehilangan titik koma sebelumnyafi
.