La nullglobopción (que por cierto es una zshinvención, solo añadida años después a bash( 2.0)) no sería ideal en varios casos. Y lses un buen ejemplo:
ls *.txt
O su equivalente más correcto:
ls -- *.txt
Con nullglobon se ejecutaría lssin ningún argumento que se trata como ls -- .(enumere el directorio actual) si no coinciden los archivos, lo que probablemente sea peor que llamar lscon un literal *.txtcomo argumento.
Tendría problemas similares con la mayoría de las utilidades de texto:
grep foo *.txt
Buscaría foola entrada estándar si no hay txtarchivo.
Un valor predeterminado más sensato, y el de csh, tcsh, zsh o fish 2.3+ (y de los primeros shells de Unix) es cancelar el comando por completo si el glob no coincide.
bash(desde la versión 3) tiene una failglobopción para eso (interesante para esta discusión, ya que al contrario de ashAT&T ksho zsh, bashno admite ámbitos locales para las opciones (aunque eso cambiará en 4.4), esa opción cuando está habilitada globalmente rompe algunas cosas como las funciones bash-complete).
Tenga en cuenta que csh y tcsh son ligeramente diferentes de zsh, fisho bash -O failgloben casos como:
ls -- *.txt *.html
Donde necesita que todos los globos no coincidan para que se cancele el comando. Por ejemplo, si hay un archivo txt y ningún archivo html, se convierte en:
ls -- file.txt
Usted puede conseguir que el comportamiento con zshla setopt cshnullglobaunque de una manera más sensata de hacerlo en zshsería utilizar un pegote como:
ls -- *.(txt|html)
En zshy ksh93, también puede aplicar nullglob en función de cada globo, que es un enfoque mucho más sensato que modificar una configuración global:
files=(*.txt(N)) # zsh
files=(~(N)*.txt) # ksh93
crearía una matriz vacía si no hay un txtarchivo en lugar de fallar el comando con un error (o convertirlo en una matriz con un *.txtargumento literal con otros shells).
Las versiones fishanteriores a la 2.3 funcionarían de la misma manera bash -O nullglobpero darían una advertencia cuando sean interactivas cuando un globo no tenga coincidencia. Desde 2.3, funciona como zshexcepto para los globos utilizados en for, seto count.
Ahora, en la nota del historial, el comportamiento fue realmente roto por el shell Bourne. En versiones anteriores de Unix, el bloqueo se realizaba a través del /etc/globayudante y ese ayudante se comportaba como csh: fallaría el comando si ninguno de los globos coincidía con ningún archivo y, de lo contrario, eliminaría los globos sin coincidencia.
Entonces, la situación en la que estamos hoy se debe a una mala decisión tomada en el shell Bourne.
Tenga en cuenta que el shell Bourne (y el shell C) vienen con otra nueva característica de Unix: el entorno. Eso significa la expansión de variables (su predecesor sólo tenía los $1, $2... parámetros posicionales). El shell Bourne también introdujo la sustitución de comandos.
Otra mala decisión de diseño del shell Bourne fue realizar el bloqueo (y la división) tras la expansión de las variables y la sustitución de comandos (posiblemente por compatibilidad con el shell Thompson, donde echo $1aún se invocaría /etc/globsi $1contuviera comodines (era más como una expansión de macro preprocesador). allí, como en el valor expandido, se analizó nuevamente como código shell)).
Los globos fallidos que no coinciden significarían, por ejemplo, que:
pattern='a.*b'
grep $pattern file
fallaría el comando (a menos que haya algunos a.whateverbarchivos en el directorio actual). csh(que también realiza el bloqueo en la expansión variable) falla el comando en ese caso (y diría que es mejor que dejar un error latente allí, incluso si no es tan bueno como no hacerlo en absoluto zsh).