bash for-loop wildcard shopt

bash - ¿Cómo omitir el bucle for cuando no hay archivos coincidentes?



for-loop wildcard (2)

La forma estándar de hacer esto (si no puede o no quiere usar nullglob ) es simplemente verificar si el archivo existe.

for file in foo*; do [ -f "$file" ] || continue ... done

La sobrecarga de verificar cada valor de $file es necesaria porque si $file expande a foo* , todavía no sabe si realmente hubo un archivo llamado foo* (porque coincide con el patrón) o si el patrón no pudo coincidir y expandido a sí mismo. El uso de nullglob , por supuesto, elimina esa ambigüedad porque una expansión fallida no produce argumentos y el ciclo en sí nunca ejecuta el cuerpo.

Cuando recorro todos los archivos comenzando por foo lo hago

for f in foo* ; do echo "result = $f" ; done

El problema es cuando ningún archivo comienza por foo me sale:

result = foo*

Lo que significa que el bucle se ejecuta una vez, incluso si ningún archivo comienza por foo .

¿Cómo es esto posible? ¿Cómo puedo recorrer todos los archivos (y no recorrerlo si no hay ningún archivo)?


Puede detener este comportamiento estableciendo nullglob :

shopt -s nullglob

Desde la página vinculada:

nullglob es una opción de shell Bash que modifica la expansión [[glob]] de tal manera que los patrones que no coinciden con ningún archivo se expanden a cero argumentos, en lugar de a sí mismos.

Puede eliminar esta configuración con -u (sin establecer, mientras que s es para establecer):

shopt -u nullglob

Prueba

$ touch foo1 foo2 foo3 $ for file in foo*; do echo "$file"; done foo1 foo2 foo3 $ rm foo*

Veamos:

$ for file in foo*; do echo "$file"; done foo*

Configuración de nullglob :

$ shopt -s nullglob $ for file in foo*; do echo "$file"; done $

Y luego deshabilitamos el comportamiento:

$ shopt -u nullglob $ for file in foo*; do echo "$file"; done foo*