[ -f /*.txt ]
retornará true somente se houver um (e apenas um) arquivo não oculto em /cujo nome termina .txte se esse arquivo for um arquivo regular ou um link simbólico para um arquivo regular.
Isso ocorre porque os curingas são expandidos pelo shell antes de serem passados para o comando (aqui [).
Portanto, se há um /a.txte /b.txt, [serão passados 5 argumentos: [, -f, /a.txt, /b.txte ]. [reclamaria que -fé dado muitos argumentos.
Se você deseja verificar se o *.txtpadrão se expande para pelo menos um arquivo não oculto (regular ou não):
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é bashespecífico, mas escudos como ksh93, zsh, yash, tcshtem declarações equivalentes.
Observe que ele encontra esses arquivos lendo o conteúdo do diretório; ele não tenta acessar esses arquivos, o que o torna mais eficiente do que soluções que chamam comandos como lsou statnessa lista de arquivos computados pelo shell.
O shequivalente padrão seria:
set -- [*].txt *.txt
case "$1$2" in
('[*].txt*.txt') ;;
(*) shift; script "$@"
esac
O problema é que, com os shells Bourne ou POSIX, se um padrão não corresponde, ele se expande. Portanto, se *.txtexpandir *.txt, você não sabe se é porque não há .txtarquivo no diretório ou porque existe um arquivo chamado *.txt. Usando[*].txt *.txt permite discriminar entre os dois.
/? Além disso, falta um ponto e vírgula antesfi.