Evitar errores debido al asterisco no expandido

En bash a menudo uso for-loops como el siguiente

for file in *.type; do sommecommand "$file"; done; 

para realizar una operación para todos los files que coincidan con *.type . Si no se encuentra ningún file con esta terminación en los directorys de trabajo, el asterisco no está expandido y generalmente recibiré un post de error que indica que algún command no encontró el file. Inmediatamente puedo pensar en varias forms de evitar este error. Pero agregar un condicional no parece ser muy elegante. ¿Hay una manera corta y limpia de lograr esto?

Sí, ejecuta el siguiente command:

 shopt -s nullglob 

anulará la coincidencia y no se desencadenará ningún error.

  • si desea este comportamiento por defecto, agregue el command en su ~/.bashrc
  • si quieres detectar un glob nulo en el shell POSIX, testing

     for i in *.txt; do [ "$i" = '*.txt' ] && [ ! -e '*.txt' ] && continue done 

Ver http://mywiki.wooledge.org/NullGlob

En bash puedes usar shopt -s nullglob para expandir a una matriz vacía si no hay coincidencias.

En shells POSIX sin nullglob , puede evitar este problema comprobando que el nombre de file que se pasa realmente existe al tener [ -e "$file" ] || [ -L "$file" ] || continue [ -e "$file" ] || [ -L "$file" ] || continue [ -e "$file" ] || [ -L "$file" ] || continue como la primera parte de tu ciclo for .

La técnica habitual para shells que no tienen una opción nullglob es

 set -- [*].type *.type case $1$2 in '[*].type*.type') shift 2;; *) shift esac for file do cmd -- "$file" done 

El tipo extra [*].type Es para cubrir el caso donde hay un file llamado *.type en el directory actual.

Ahora, si desea include files de puntos, eso se vuelve más complicado .

Creo que esa técnica fue acuñada por Laura Fairhead en usenet hace unos años.

find . -name '*.type' -maxdepth 0 -exec somecommand "{}" ";"

Esto elimina for completo el bucle for y el globbing del shell de la ecuación. find ejecutará el command -exec una vez por coincidencia, y si no hay coincidencias, nunca se ejecutará. La function -maxdepth 0 indica que no se repita en los subdirectorys del argumento de ruta nombrado ( . , En este caso).

La desventaja es que implica otra aplicación, aunque presente en prácticamente todos los sistemas Linux (y probablemente también en la mayoría de los Unix).