Como hacer que bash no distinga entre mayúsculas y minúsculas

AdriMcGrady 31/03/2023

El objetivo de este post es tan simple como lo que dice su título. ¿Cómo hacer que bash no distinga entre mayúsculas o minúsculas? O lo que es lo mismo… ¿Cómo hacer que bash trabaje en modo case insensitive?

Que bash trabaje en modo case sensitive no es un capricho ni es algo exclusivo de la propia shell bash. ¿Y por qué? Pues la verdad es que no lo he hablado con Dennis Ritchie, Ken Thompson ni Linus Torvlads, pero si tengo una frase grabada de una de mis primeras prácticas de la asignatura de Sistemas Operativos en la universidad:

En Linux todo es un fichero.

Y teniendo en cuenta que la inmensa mayoría de los sistemas de ficheros para Linux y Unix son case sensitive, o lo que es lo mismo, distinguen entre mayúsculas y minúsculas… Que bash, la shell de la que estamos hablando distinga entre mayúsculas y minúsculas cae por su propio peso.

Pero, a veces, nos interesa que el comportamiento sea distinto para que trabaje de modo que no haya distinción entre mayúsculas y minúsculas. Por ejemplo, en el artículo Tratamiento y conversión de imágenes con ImageMagick (II) Aplicación a densidades de pantalla de Android se buscan las imágenes originales en base a su extensión definida por el tipo de formato origen que se pasaba como parámetros. Por ejemplo, si bash trabajara en su modo “normal” los ficheros .png y .PNG no serían tratados igual. Lo que nos lleva al meollo de este post.

¿Como hacer que bash no distinga entre mayúsculas y minúsculas?

Antes de explicar como hacer que bash no haga distinción entre mayúsculas y minúsculas, voy a poner un ejemplo de su funcionamiento original (case sensitive).

# Tenemos 2 ficheros de texto en nuestro directorio de pruebas, pero uno tiene la extensión en maýusculas
adrimcgrady@nanopifire3:~/noroute2host-pruebas$ ls -1 fichero*
fichero1.txt
fichero2.TXT

# Si listamos los ficheros *.txt solo nos aparece uno de ellos
adrimcgrady@nanopifire3:~/noroute2host-pruebas$ ls -1 *.txt
fichero1.txt

# Y lo mismo para el caso de *.TXT
adrimcgrady@nanopifire3:~/noroute2host-pruebas$ ls -1 *.TXT
fichero2.TXT

Pero ¿y si queremos listar todos los ficheros de texto con extensión txt sin importar si está en mayúsculas o minúsculas? Pues que en el caso de bash, existe la posibilidad de hacer que no distinga entre mayúsculas y minúsculas para el caso de ficheros y directorios. La responsable es la función incorporada de bash shopt. Esta función permite activar o desactivar bastantes aspectos de bash que modifican como se comporta por defecto en diferentes aspectos. Su uso básico es bastante simple:

# Activar una opción
shopt -s OPCIÓN

# Desactivar una opción
shopt -u OPCIÓN

Y para la opción de la distinción entre mayúsculas y minúsculas, el nombre no es demasiado original: nocaseglob. Así que para activar o desactivar la opción sería tan simple como:

# Activar modo case-insensitive
shopt -s nocaseglob

# Volver al modo case-sensitive
shopt -u nocaseglob

Por tanto, si activamos la opción, y volvemos a listar los ficheros .txt del directorio de pruebas veremos como ahora si se listan todos independientemente de si su extensión está en minúsculas o mayúsculas.

adrimcgrady@nanopifire3:~/noroute2host-pruebas$ shopt -s nocaseglob

adrimcgrady@nanopifire3:~/noroute2host-pruebas$ ls -1 *.txt
fichero1.txt
fichero2.TXT

Mostrar el estado de las opciones de shopt

Como he comentado antes shopt provee una gran cantidad de modificadores de comportamiento de la shell bash. Y podemos listar el estado de todas ellas en cualquier momento simplemente ejecutando la función incorporada shopt.

adrimcgrady@nanopifire3:~$ shopt
autocd          off
assoc_expand_once   off
cdable_vars     off
cdspell         off
checkhash       off
checkjobs       off
checkwinsize    on
cmdhist         on
compat31        off
compat32        off
compat40        off
compat41        off
compat42        off
compat43        off
compat44        off
complete_fullquote  on
direxpand       off
dirspell        off
dotglob         off
execfail        off
expand_aliases  on
extdebug        off
extglob         off
extquote        on
failglob        off
force_fignore   on
globasciiranges on
globstar        off
gnu_errfmt      off
histappend      on
histreedit      off
histverify      off
hostcomplete    on
huponexit       off
inherit_errexit off
interactive_comments    on
lastpipe        off
lithist         off
localvar_inherit    off
localvar_unset  off
login_shell     on
mailwarn        off
no_empty_cmd_completion off
nocaseglob      off
nocasematch     off
nullglob        off
progcomp        on
progcomp_alias  off
promptvars      on
restricted_shell    off
shift_verbose   off
sourcepath      on
xpg_echo        off

Si, por el contrario, solo queremos listar es estado de una de las opciones la sintaxis sería la siguiente:

shopt [NOMBRE_OPCIÓN]

Por ejemplo, para ver el estado de la opción nocaseglob, cambiar su comportamiento y volver a listar el estado sería así de simple:

# Comprobar el estado antes de cambiar la opción
adrimcgrady@nanopifire3:~$ shopt nocaseglob
nocaseglob      off

# Activar nocaseglob
adrimcgrady@nanopifire3:~$ shopt -s nocaseglob

# Volver a comprobar el estado de la opción nocaseglob
adrimcgrady@nanopifire3:~$ shopt nocaseglob
nocaseglob      on

Por último, solo añadir que las opciones y modificadores que se pueden activar y desactivar con shopt son válidas mientras la sesión de la shell esté activa. Por lo que al salir de la sesión volverán a su estado por defecto

Puedes hacer permanente estos cambios añadiendo el comando shopt al fichero .bashrc, pero en el caso de nocaseglob no te lo recomiendo porque puede afectar a scripts o comandos el sistema que se lancen dentro de una shell bash.

Es más, como ya he comentado la opción tiene validez para toda la sesión por lo que tienes que tener cuidado si no la desactivas cuando no la necesites. Por ejemplo, si la activas dentro de un script y no la desactivas, afectará a todo el script. Puedes ver un ejemplo de como activarla cuando sea necesario y desactivarla después en el script 0018_generar_drawables_dpi.sh del que te hablo en el artículo Tratamiento y conversión de imágenes con ImageMagick (II) Aplicación a densidades de pantalla de Android

A partir de aquí, ya te toca a ti seguir investigando las opciones disponibles en shopt y ver como cambian el comportamiento por defecto de la shell bash. Aunque no descarto que aparezca por el blog en un futuro un post hablando de las opciones más comunes de shopt

Enlaces de interés:

Artículo anterior Artículo siguiente

Artículos relacionados: