Cuando empiezas a tirar código Shell con cierta soltura empiezas a meter validaciones digamos que básicas, ¿existe el fichero de configuración de este proceso?, ¿y la ruta del fichero de log que voy a grabar?, ¿el fichero de datos a procesar existe? ¿lo puedo leer? ¿y además tiene datos o está vacio?
A todas estas preguntas y a bastantes más podemos dar respuesta con un simple IF y la correspondiente evaluación del fichero/directorio.
Utilizaremos la expresión de test, la cual podemos expresar con estas tres sintaxis:
test EXPRESION [ EXPRESION ] [[ EXPRESION ]]
Por cuestiones de portabilidad, si quieres que el script que vas a hacer sea utilizable en el mayor número de sistemas posible, te recomiendo que uses la sintaxis de «test» pues parece estar disponible en todas las shelll basada en norma POSIX.
La primera comprobación, la más básica que podemos hacer es comprobar si el elemento existe, sea un fichero, un directorio o un enlace, para essto emplearemos la opción -e
ahernan:/tmp$ FIC=/tmp/pp ahernan:/tmp$ if test -e "$FIC"; then echo "$FIC existe"; fi /tmp/pp existe
Si queremos afinar un poco más y preguntar si además de existir, sí se trata de un fichero, empleraremos la opción -f
ahernan:/tmp$ FIC=/tmp/pp ahernan:/tmp$ if test -f "$FIC"; then echo "$FIC existe y es un fichero regular"; fi /tmp/pp existe y es un fichero regular
Utilizando los otros formataos de expresar el «test», serían algo así como esto que os pongo a continuación, donde se ejecuta la parte a la derecha de los &&
cuando el resultado de la evaluación del test es verdadero, o a la derecha de los ||
cuando la evaluación del test es falso.
ahernan:/tmp$ FIC=/tmp/pp ahernan:/tmp$ [[ -f $FIC ]] && echo "$FIC existe y es un fichero regular" || echo "$FIC no existe o no es un fichero regular" /tmp/pp existe y es un fichero regular
Como veis, la potencia del comando reside en el parámetro que utilicemos. A continuación os enumero bastantes de sus opciones, no todas, pero si las que me parecen más útiles:
Tipo del descriptor:
-b | Devuelve TRUE si existe y se trata de un Block device o special block file |
-c | Devuelve TRUE si exsite y se trata de un fichero de caracteres |
-d | Devuelve TRUE si existe y es un directorio |
-f | Devuelve TRUE si existe y es un fichero regular. |
-S | Devuelve TRUE si existe y es un socket. |
-p | Devuelve TRUE si existe y es un pipe |
-L | Devuelve TRUE si existe y es un enlace simbólico |
-h | Devuelve TRUE si existe y es un enlace simbólico |
Permisos del descriptor:
-u | Devuelve TRUE si existe y tiene el flag de set-user-id (suid) activo |
-g | Devuelve TRUE si existe y tiene el flag de set-group-id (sgid) activo |
-k | Devuelve TRUE si existe y activo el flag de sticky bit |
-w | Devuelve TRUE si existe y es escribible |
-x | Devuelve TRUE si existe y es ejecutable |
-r | Devuelve TRUE si existe y es leible |
Otros acerca del descriptor:
-s | Devuelve TRUE si existe y tienen tamaño distinto de 0 |
-G | Devuelve TRUE si existe y el descriptor tiene el mismo grupo que el usuario que ejecuta el comando |
-O | Devuelve TRUE si exsite y el descriptor tiene el mismo propietario que el usuario que ejecuta el comando |