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