L’ nullgloboption (BTW étant une zshinvention ajoutée seulement des années plus tard à bash( 2.0)) ne serait pas idéale dans un certain nombre de cas. Et lsest un bon exemple:
ls *.txt
Ou son équivalent plus correct:
ls -- *.txt
Avec nullglobon serait exécuté lssans argument considéré comme ls -- .(liste le répertoire en cours) si aucun fichier ne correspond, ce qui est probablement pire que d'appeler lsavec un littéral *.txtcomme argument.
Vous auriez des problèmes similaires avec la plupart des utilitaires de texte:
grep foo *.txt
Chercherais foosur stdin s'il n'y a pas de txtfichier.
Un choix plus judicieux, et celui de csh, tcsh, zsh ou fish 2.3+ (et des premiers shells Unix) consiste à annuler la commande si le glob ne correspond pas.
bash(depuis la version 3) a une failgloboption pour cela (intéressant pour cette discussion, car contrairement à ashAT & T kshou zsh, bashne supporte pas les étendues locales pour les options (bien que cela change dans la version 4.4), cette option, lorsqu'elle est activée globalement, casse quelques problèmes comme les fonctions d'achèvement de bash).
Notez que csh et tcsh sont légèrement différentes de zsh, fishou bash -O failglobdans des cas comme:
ls -- *.txt *.html
Où vous avez besoin que tous les globs ne correspondent pas pour que la commande soit annulée. Par exemple, s'il existe un fichier txt et aucun fichier html, cela devient:
ls -- file.txt
Vous pouvez obtenir ce comportement avec zshavec setopt cshnullglobbien d' une manière plus raisonnable de le faire en zshserait d'utiliser un glob comme:
ls -- *.(txt|html)
Dans zshet ksh93, vous pouvez également appliquer nullglob sur une base globale, ce qui est une approche beaucoup plus saine que de modifier un paramètre global:
files=(*.txt(N)) # zsh
files=(~(N)*.txt) # ksh93
créerait un tableau vide s'il n'y avait pas de txtfichier au lieu d'échouer la commande avec une erreur (ou d'en faire un tableau avec un *.txtargument littéral avec d'autres shells).
Les versions fishantérieures à 2.3 fonctionneraient de la même façon, bash -O nullglobmais donneraient un avertissement lorsqu'elles sont interactives lorsqu'un glob n'a pas de correspondance Depuis la version 2.3, cela fonctionne comme zshsauf pour les globs utilisés dans for, setou count.
Sur la note d’histoire, le comportement a en fait été interrompu par le shell Bourne. Dans les versions précédentes d'Unix, la globulation était effectuée via l' /etc/globassistant et ce dernier se comportait comme suit csh: la commande échouerait si aucun des globs ne correspondait à un fichier et supprimait les globs sans correspondance sinon.
La situation dans laquelle nous nous trouvons aujourd’hui est donc due à une mauvaise décision prise dans le shell Bourne.
Notez que le shell Bourne (et le shell C) est accompagné d’une autre nouvelle fonctionnalité Unix: l’environnement. Cette expansion signifiait variable (son prédécesseur avait seulement les $1, $2... les paramètres de position). Le shell Bourne a également introduit la substitution de commande.
Une autre décision d' une mauvaise conception de la coque Bourne était de réaliser globbing (et le fractionnement) lors de l'expansion des variables et la substitution de commande (éventuellement pour une compatibilité descendante avec la coque Thompson où echo $1invoquerais encore /etc/globsi les $1caractères génériques contenus (il a été plus comme extension macro pré-processeur là, comme dans la valeur développée a été analysé à nouveau comme un code shell)).
Des globs défaillants qui ne correspondent pas signifieraient par exemple que:
pattern='a.*b'
grep $pattern file
échouerait la commande (à moins que certains a.whateverbfichiers ne se trouvent dans le répertoire en cours). cshDans ce cas, la commande échoue (et je dirais que c'est mieux que de laisser un bogue en sommeil ici, même s'il n'est pas aussi bon que de ne pas faire de globing du tout comme dans zsh).