L' nullglobopzione (che BTW è zshun'invenzione, aggiunta solo anni dopo a bash( 2.0)) non sarebbe l'ideale in un numero di casi. Ed lsè un buon esempio:
ls *.txt
O il suo equivalente più corretto:
ls -- *.txt
Con nullglobon verrebbe eseguito lssenza alcun argomento che viene trattato come ls -- .(elenca la directory corrente) se nessun file corrisponde, il che è probabilmente peggio che chiamare lscon un letterale *.txtcome argomento.
Avresti problemi simili con la maggior parte delle utility di testo:
grep foo *.txt
Sarebbe cercare foosu stdin se non c'è txtil file.
Un default più sensato, e quello di csh, tcsh, zsh o fish 2.3+ (e delle prime shell Unix) è annullare del tutto il comando se il glob non corrisponde.
bash(dalla versione 3) ha failglobun'opzione per questo (interessante per questa discussione, poiché contrariamente a ash, AT&T ksho zsh, bashnon supporta gli ambiti locali per le opzioni (anche se questo è cambiare in 4.4), quell'opzione quando abilitata a livello globale interrompe alcune cose come le funzioni di completamento bash).
Nota che csh e tcsh sono leggermente diversi da zsh, fisho bash -O failglobin casi come:
ls -- *.txt *.html
Dove sono necessari tutti i globs per non corrispondere affinché il comando venga annullato. Ad esempio, se esiste un file txt e nessun file html, questo diventa:
ls -- file.txt
È possibile ottenere che il comportamento con zshcon setopt cshnullglobse un modo più sensato di farlo in zshsarebbe quello di utilizzare un glob come:
ls -- *.(txt|html)
In zshe ksh93, puoi anche applicare nullglob su base per-glob, che è un approccio molto più sano rispetto alla modifica di un'impostazione globale:
files=(*.txt(N)) # zsh
files=(~(N)*.txt) # ksh93
creerebbe un array vuoto se non ci sono txtfile invece di fallire il comando con un errore (o renderlo un array con un *.txtargomento letterale con altre shell).
Le versioni fishprecedenti alla 2.3 funzionerebbero come bash -O nullglobma darebbero un avvertimento quando interattivo quando un glob non ha corrispondenza. Dal 2.3, funziona come zshtranne per i globs usati in for, seto count.
Ora, sulla nota della storia, il comportamento è stato effettivamente rotto dalla shell Bourne. Nelle versioni precedenti di Unix, il globbing veniva eseguito tramite l' /etc/globhelper e quell'helper si comportava in modo simile csh: avrebbe fallito il comando se nessuno dei glob avesse corrispondenza con qualsiasi file e avrebbe rimosso i globs senza alcuna corrispondenza.
Quindi la situazione in cui ci troviamo oggi è dovuta a una decisione sbagliata presa nella shell Bourne.
Si noti che la shell Bourne (e la shell C) è arrivata con un'altra nuova funzionalità Unix: l'ambiente. Ciò significava espansione variabile (il suo predecessore aveva solo i $1, $2... parametri posizionali). La shell Bourne ha anche introdotto la sostituzione dei comandi.
Un'altra cattiva decisione di progettazione della shell Bourne è stata quella di eseguire il globbing (e la divisione) sull'espansione delle variabili e la sostituzione dei comandi (probabilmente per la compatibilità con le versioni precedenti della shell Thompson dove echo $1sarebbe comunque invocare /etc/globse $1contenesse caratteri jolly (era più simile all'espansione macro pre-processore) lì, come nel valore espanso è stato nuovamente analizzato come codice shell)).
I globs non corrispondenti che non corrispondono significherebbero ad esempio che:
pattern='a.*b'
grep $pattern file
fallirebbe il comando (a meno che non ci siano alcuni a.whateverbfile nella directory corrente). csh(che esegue anche globbing in caso di espansione variabile) in quel caso fallisce il comando (e direi che è meglio che lasciare un bug dormiente lì, anche se non è buono come non fare globbing come in zsh).