[ -f /*.txt ]
renvoie true uniquement s'il existe un (et un seul) fichier non masqué /dont le nom se termine .txtet si ce fichier est un fichier normal ou un lien symbolique vers un fichier normal.
En effet, les caractères génériques sont développés par le shell avant d'être transmis à la commande (ici [).
Donc , s'il y a un /a.txtet /b.txt, [sera transmis 5 arguments: [, -f, /a.txt, /b.txtet ]. [se plaindrait alors qu'on -flui donne trop d'arguments.
Si vous souhaitez vérifier que le *.txtmodèle se développe en au moins un fichier non caché (normal ou non):
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 nullglobest bashspécifique, mais des coquilles comme ksh93, zsh, yash, tcshont des déclarations équivalentes.
Notez qu'il trouve ces fichiers en lisant le contenu du répertoire, il n'essaie pas du tout d'accéder à ces fichiers, ce qui le rend plus efficace que les solutions qui appellent des commandes comme lsou statsur cette liste de fichiers calculée par le shell.
L' shéquivalent standard serait:
set -- [*].txt *.txt
case "$1$2" in
('[*].txt*.txt') ;;
(*) shift; script "$@"
esac
Le problème est qu'avec les shells Bourne ou POSIX, si un modèle ne correspond pas, il se développe lui-même. Donc, si se *.txtdéveloppe en *.txt, vous ne savez pas si c'est parce qu'il n'y a pas de .txtfichier dans le répertoire ou parce qu'il y a un fichier appelé *.txt. L'utilisation [*].txt *.txtpermet de distinguer les deux.
/? De plus, il vous manque un point-virgule avantfi.