[ -f /*.txt ]
renvoie true uniquement s'il existe un (et un seul) fichier non masqué /
dont le nom se termine .txt
et 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.txt
et /b.txt
, [
sera transmis 5 arguments: [
, -f
, /a.txt
, /b.txt
et ]
. [
se plaindrait alors qu'on -f
lui donne trop d'arguments.
Si vous souhaitez vérifier que le *.txt
modè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 nullglob
est bash
spécifique, mais des coquilles comme ksh93
, zsh
, yash
, tcsh
ont 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 ls
ou stat
sur 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 *.txt
développe en *.txt
, vous ne savez pas si c'est parce qu'il n'y a pas de .txt
fichier dans le répertoire ou parce qu'il y a un fichier appelé *.txt
. L'utilisation [*].txt *.txt
permet de distinguer les deux.
/
? De plus, il vous manque un point-virgule avantfi
.