14 de Junio, 2004

Pequeñas diferencias shell

Lo que hablaba de diferencias entre los distintos Shell UNIX. Un ejemplo:

$ ls +(aa|bb)*
bash: syntax error near unexpected token `('

Esto es BASH (valga la redundancia, que ya lo dice el error).

Acostumbrado a usar esos patrones de sustitución en el pdksh (public domain korn shell, el /bin/sh de OpenBSD), me he quedado en 'shock' durante unos segundos al ver ese comportamiento.

He pedido que muestre los ficheros que empiecen por 'aa' o 'bb', independiente del resto del nombre.

No ha funcionado, aunque en la página del manual de BASH aparecen estos patrones de sustitución, hay que activarlos con shopt. Concretamente con shopt -s extblog. Entonces sí se comporta como yo esperaba:

$ ls +(aa|bb)*
aa  aabb  bb

Esos son los tres ficheros que hay en el directorio que se ajustan a mi petición: aa, bb y aabb. Los nombres están preparados para este ejemplo, aunque a mi me ha pasado con una situación completamente real.

Me he puesto a pensar si es que pido cosas demasiado extrañas que requieran activar algo que en el manual de BASH llaman 'extensión', y parece que así es :o. Se trata de extended pattern matching según dicho manual, y no está disponible en Bourne Shell (recordemos que BASH es Bourne Again SHell, con lo que tiene sentido que preserven esa compatibilidad).

¿Qué alternativas tengo? Los patrones normales no permiten comparar pares de caracteres (aa o bb). Pensando un poco la única solución que he encontrado es expandir los parámetros para ls:

$ ls {aa,bb}*
aa  aabb  bb

Que en este caso funciona (y en mi situación real también ha valido), pero no es lo mismo.

La diferencia está en que el shell expande ls {aa,bb}* en algo como ls aa* bb*, mientras que con +(aa|bb)* es solo una llamada a ls.

Un ejemplo que no da el mismo resultado sería:

$ shopt -s extglob
$ ls /*+(linuz|old)*
/vmlinuz  /vmlinuz.old
$ ls /*{linuz,old}*
/vmlinuz  /vmlinuz.old  /vmlinuz.old

Está claro que no tengo dos ficheros iguales con el mismo nombre en la raíz de homeworld ;).

Anotación por Juan J. Martínez.

Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.