[ -f /*.txt ]
zwróciłoby wartość prawdy tylko wtedy, gdy istnieje jeden (i tylko jeden) plik, /którego nazwa się nie kończy, .txti jeśli jest to zwykły plik lub dowiązanie symboliczne do zwykłego pliku.
Jest tak, ponieważ symbole wieloznaczne są rozszerzane przez powłokę przed przekazaniem do polecenia (tutaj [).
Więc jeśli istnieje /a.txti /b.txt, [zostanie przekazany 5 argumentów: [, -f, /a.txt, /b.txti ]. [skarżyłby się wtedy na -fzbyt wiele argumentów.
Jeśli chcesz sprawdzić, czy *.txtwzorzec rozwija się do co najmniej jednego nie ukrytego pliku (zwykłego lub nie):
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 nullglobjest bashspecyficzny, ale muszle podoba ksh93, zsh, yash, tcshmają te same oświadczenia.
Zauważ, że znajduje te pliki, czytając zawartość katalogu, wcale nie próbuje uzyskać dostępu do tych plików, co czyni go bardziej wydajnym niż rozwiązania, które wywołują polecenia takie jak lslub statna tej liście plików obliczonych przez powłokę.
Standardowy shodpowiednik to:
set -- [*].txt *.txt
case "$1$2" in
('[*].txt*.txt') ;;
(*) shift; script "$@"
esac
Problem polega na tym, że w przypadku powłok Bourne lub POSIX, jeśli wzorzec nie pasuje, rozwija się do siebie. Jeśli więc zostanie *.txtrozwinięty *.txt, nie wiesz, czy to dlatego, że nie ma .txtpliku w katalogu, czy dlatego, że istnieje jeden plik o nazwie *.txt. Korzystanie [*].txt *.txtpozwala na rozróżnienie między nimi.
/? Ponadto brakuje Ci wcześniej średnikafi.