En la mayoría de las conchas nullglobno es el valor predeterminado. Eso significa, por ejemplo, si ejecuta este comando
ls *
en un directorio vacío, expandirá el *globo a un literal *, en lugar de a una lista vacía de argumentos. Hay formas de cambiar ese comportamiento, de modo que *en un directorio vacío devolverá una lista vacía de argumentos, lo que parecería más intuitivo.
Entonces, ¿hay alguna razón por la que nullglobestá deshabilitada de forma predeterminada? Si es así, ¿cuál es esa razón?

*es un problema y se expande a todos los archivos existentes ; ¿Cómo es "intuitivo" que haya un caso especial en el que los globos de directorio vacíos se "expandan" a un literal*?Respuestas:
La
nullglobopción (que por cierto es unazshinvención, solo añadida años después abash(2.0)) no sería ideal en varios casos. Ylses un buen ejemplo:O su equivalente más correcto:
Con
nullglobon se ejecutaríalssin ningún argumento que se trata comols -- .(enumere el directorio actual) si no coinciden los archivos, lo que probablemente sea peor que llamarlscon un literal*.txtcomo argumento.Tendría problemas similares con la mayoría de las utilidades de texto:
Buscaría
foola entrada estándar si no haytxtarchivo.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 unafailglobopción para eso (interesante para esta discusión, ya que al contrario deashAT&Tkshozsh,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,fishobash -O failgloben casos como: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:
Usted puede conseguir que el comportamiento con
zshlasetopt cshnullglobaunque de una manera más sensata de hacerlo enzshsería utilizar un pegote como:En
zshyksh93, 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: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 manerabash -O nullglobpero darían una advertencia cuando sean interactivas cuando un globo no tenga coincidencia. Desde 2.3, funciona comozshexcepto para los globos utilizados enfor,setocount.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 comocsh: 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:
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 absolutozsh).fuente
nullglobparece romper la finalización de tabulación (presionar la tecla tab no hace nada cuando está habilitado).files=$(shopt -s nullglob;echo *.txt)xpg_echo) en variables escalares . Necesitaría algo comoreadarray -td '' files < <(shopt -s nullglob; printf '%s\0' *.txt)conbash4.4 o superior o(shopt -s nullglob; printf '%s\0' *.txt) | xargs -r0 cmdcon GNUxargspara que sea utilizable con nombres de archivo arbitrarios. O, aún con bash4.4, use una función auxiliar que uselocal -(copiada de ceniza 25 años después) para un alcance local de opciones.