El comando if nos permite utilizar sentencias condicionales de selección simple en nuestros scripts.
Nos va a permitir ejecutar comandos si se cumple una condición o ejecutar una serie de comandos si se da la condición y si no ejecutar otros distintos. Por último, if nos permitirá ejecutar una serie de comandos en función de una serie de condiciones encadenadas (ya lo veremos con calma).
Por lo pronto vamos a echar un vistazo a la ayuda del comando if.
Las ORDENES que aparecen detrás del comando if son una lista de comandos, que habitualmente es un solo comando. Si la salida del comando es un cero, entonces se cumple la condición del if y se ejecutan los comandos detrás del then.
Es decir, la condición del if es el código de retorno del comando ejecutado.
if ls /homes; then ….
Si el comando ls /homes retorna un código de error, entonces no se cumple la condición. Si el comando ls /homes retorna un código de éxito, que es un 0, entonces se cumple la condición.
Vamos a probarlo…
El código de retorno del programa lo decide el programa. Lo importante es que:
- Si todo ha ido bien, no hay errores, debe devolver un 0.
- Si ha habido algún error, se debe devolver un valor distinto de 0. Algunos programas, en función del error devolverán un código de error u otro.
if comando; then … fi
Esta es la forma más simple del comando if para implementar una sentencia condicional if..then..fi.
Si el comando id con el valor de la variable $user no funciona correctamente, porque estamos usando una negación, entonces se ejecutarán los comandos de las líneas 12 y 13.
Ejemplos de uso con scripts
if01.sh
Funciona, pero la salida del comando ping se muestra en pantalla. En un par de versiones lo solucionamos (sigue leyendo y lo verás)
Versión 02 – Mensaje de conexión y no conexión.
Si no tenemos conexión, vamos a mostrar un mensaje indicando que no tenemos conexión con el host o equipo remoto.
Versión 03 – Equipo a comprobar por parámetro
Ahora queremos que el usuario proporcione el nombre o la dirección IP del equipo por parámetro. De esta forma, en el primer parámetro se espera recibir una dirección IP (8.8.8.8) o un nombre de dominio completo que apunte a un equipo en Internet / Red (www.educatica.es).
El primer paso sería utilizar una variable que guarde el nombre del host remoto o equipo remoto.
Ahora modificamos el código para utilizar la variable en lugar de el valor literal 8.8.8.8 que hemos usado hasta ahora. El script quedaría así:
Versión 04 – Mensajes del comando if
Si nos fijamos la condición del if es el comando ping. Este comando muestra en pantalla, en salida estándar, información de lo que va haciendo. De la misma forma, si hay un error mostrará por la salida de error, que por defecto es la pantalla, un mensaje.
Esta información en nuestro script, dificulta la lectura de los mensajes que nosotros le mostramos al usuario, puesto que se mezclan con los del comando ping.
Estaría muy bien, que no se mostrara ningún mensaje de la ejecución del comando ping que está en la condición del comando if en pantalla.
La primera aproximación sería redirigir la salida estándar y la de errores a un fichero «basura». De esta forma, el comando ping se ejecuta pero no va a mostrar nada en pantalla. Su código de salida será usado por el comando if para determinar si entra en la rama then o en la del else.
Esta bien, funciona, no se muestra información extra o no necesaria al usuario. No obstante, se crea un fichero, que habría que borrar…
Podemos pensar en borrarlo al final del script…
Esto funciona, pero hay una alternativa mejor. Si nos da igual lo que vamos a almacenar en ese fichero, porque solo lo estamos usando para que no se muestre información no deseada en pantalla, podemos utilizar el fichero /dev/null que permite escribir el él sin que se guarde nada realmente. Es decir, es como una papelera o agujero negro: todo lo que escribamos ahí se perderá como lágrimas en la lluvia.
Ejemplo 2 – if02.sh
Este script recibirá la ruta de un fichero o directorio en el primer parámetro y tendrá que comprobar si dicho fichero existe.
Si el fichero existe, se mostrará un mensaje diciendo que existe y se mostrará información extendida del fichero con un formato comprensible por humanos. Si no existe, se mostrará un mensaje indicando que el fichero o directorio no existe.
Pista: Podéis basaros en el script anterior puesto que es relativamente parecido.
Ejemplo 03 – Comprobar si un usuario existe
Vamos a crear un script que comprobará si el nombre del usuario pasado en el primer parámetro existe en el sistema.
Si el usuario existe, mostraremos la línea de configuración de la cuenta del usuario. Si no existe, mostraremos un mensaje indicando que el usuario no existe.
Pista: Piensa cómo comprobarías tú como humano si un usuario existe o no en tu sistema. ¿Qué comando utilizarías? Requetepista: id
Versión 01 – Solución sencilla
Primero establecemos un nombre para la variable que almacenará el primer parámetro, que es el nombre del usuario para el que queremos comprobar si existe o no. El nombre de la variable, como siempre, será significativo.
El comando id permite comprobar si existe o no un usuario en el sistema.
La información que muestra el comando, así como los mensajes de error no nos interesan ni queremos mostrarlos al usuario, así que redirigimos la información a /dev/null.
Hemos usado grep para mostrar las líneas del fichero /etc/passwd que contengan la cadena de texto almacenada en la variable usuario, es decir que contengan el nombre del usuario. Le hemos añadido al grep -w para que solo muestre las líneas en las que aparezca el nombre del usuario tal cuál (palabra completa). Además, le hemos añadido ^ para indicar a grep que solo debe mostrar la líneas en las que el patrón, el nombre del usuario, aparezca al inicio de la línea.
¿Qué sucede si no pasamos parámetro? Pues que la variable usuario estará vacía y el comando que se ejecutará será id, que no dará error, puesto que mostrará información del usuario actual.
Sin embargo, se puede generar problema con el comando grep, que no utilizará ningún parámetro…
Ejemplo 05 – Comprobando si una variable está vacía
Vamos a modificar el script anterior para comprobar si el valor que se recibe por parámetro está vacío o no. Es decir, para conocer si nos pasan un valor en el primer parámetro o no.
Para ello utilizaremos el comando test. Como no conocemos el comando test, vamos a echar un ojo a su página de manual.
El comando test nos sirve para comprobar tipos de ficheros y valores (cadenas de texto y enteros). El valor de salida del comando viene determinado por la EXPRESSION.
La expresión es lo que queramos comprobar con el comando test.
And y or
Con esta última opción tenemos para trabajar…
Test no muestra nada en pantalla, tan solo retorna con código de salida 0 u otro valor en función de si la expresión que se le ha pasado por parámetro es cierta o falsa.
La pregunta del test con la expresión -z es «¿Está vacía la cadena $usuario?» en este caso, no está vacía así que el código de retorno será distinto de cero.
Y esto, ¿cómo lo usamos con un if?. Sencillo, podemos comprobar si la variable usuario, que es en la que hemos almacenado el primer parámetro, está vacía. Si está vacía, significa que no nos han pasado ningún valor en el primer parámetro,.
Ahora tendríamos que decidir qué hacemos si no nos pasan parámetro. Por ejemplo, decidimos que el usuario para el que vamos a consultar información es el usuario actual, cuyo nombre está almacenado en la variable USER.
Versión 02 – Si no se pasa parámetro, erro y terminar
Vamos a modificar el script para que si no se pasa parámetro, en lugar de tomar un valor por defecto, se muestre un mensaje de error y terminemos con la ejecución del script devolviendo un código de salida de error (distinto de cero).
Lo único que hemos cambiado es el cuerpo del then del primer if, que es el que comprueba si se ha pasado algún valor por parámetro.
Ejemplo 06 – checkUserGroup.sh
Vamos a crear un script que reciba dos parámetros, el nombre de un usuario y el de un grupo. El script deberá comprobar si el usuario pertenece al grupo proporcionado.
Adem´ás, el script comprobará si se han pasado ambos parámetros.
Versión 02 – Utilizando corchetes
Vamos a cambiar la forma en la que ejecutamos el comando test. Ahora vamos a poner la expresión que queremos comprobar entre corchetes.
El interprete de comandos detectará los corchetes y ejecutará el comando test pasándole por parámetro la expresión que esté entre corchetes. Importante: hay que dejar un espacio entre el corchete de apertura, la expresión y el corchete de cierre.
Ahora con corchetes quedaría así:
¿Qué pasa con el comando if de la línea 23? ¿Hay que ponerlo entre corchetes?
No habría que poner corchetes, porque no estamos usando el comando test. La condición de selección es el código de salida del comando que se ejecuta después del if. En este caso, no es el comando test, es una tubería compuesta por el comando groups y el comando grep.
Ejemplo 07 – addUserGroup.sh
Crea un script llamado addUserGroup.sh que reciba por parámetro el nombre de un usuario y de un grupo. Estos parámetros son obligatorios, de forma que si no se pasan el script deberá mostrar un mensaje de error y terminar la ejecución devolviendo un código de salida de error (distinto de 0).
Si el usuario no existe, creamos una nueva cuenta para este usuario.
Si el grupo no existe, creamos un nuevo grupo en el sistema.
Si el usuario no pertenece al grupo, añadimos el usuario al grupo.
Por último, mostramos información de identificación del usuario.
Comandos que es posible que necesitéis: id, groups, grep, adduser, addgroup, además de los típicos if, exit, echo…
Solución propuesta
El script debe ejecutarse como root si queremos que de verdad cree a los usuarios y grupos necesarios.
Versión 02 – Comprobar que el usuario que ejecuta el script es root
Se pide que se compruebe si el usuario que está ejecutando el script es root. Si no es root, el script deberá mostrar un mensaje de error y terminar la ejecución del script devolviendo un código de salida de error.
Podemos utilizar el comando id para comprobar si el usurio es root. Aunque podríamos utilizar otras fórmulas.
Otra forma sería utilizar el comando whoami
Vamos a comprobar como podemos comparar enteros y cadenas de caracteres.
Podemos comparar si dos cadenas de caracteres son iguales o distintas.
Podemos comparar enteros con test.
Ahora la duda es… ¿Cómo comparo el UID del usuario con el entero 0? ¿Cómo comparo el nombre del usuario con la cadena root?
¿Recordáis cómo podíamos obtener la salida de un comando en un script?. $(CMD)
Podríamos obtener la salida del comando con la herramienta $()
Cómo no vamos a usar el uid en ninguna parte posterior del programa, podríamos no usarla en absoluto, sustutiyéndola por el $(id -u) diréctamente.
Repasando, y haciendo una traza, el $(id -u) se ejecutará y la salida de dicho comando se sustituirá por esa cadena o variable. Por ejemplo, si la salida del comando es 0, realmente se ejecutará:
Si el usuario que ejecuta el script no es root, la salida de id -u será un número cualquier, posiblemente un entero a partir de 1000.
Vamos a probarlo…
Ejemplo 08 – checkFile.sh
Crea un script que reciba por parámetro la ruta de un fichero. Si no se pasa parámetro, utilizaremos como ruta por defecto el directorio personal del usuario actual.
Si el fichero no existe deberá mostrar un mensaje de error y terminar la ejecución del script.
Si existe, mostraremos información extendida con formato de tamaño comprensible por humanos del fichero o directorio, no de su contenido.
Ayuda: Mira la página de manual del comando test, porque con test se pueden hacer comprobaciones sobre ficheros y directorios.
Versión 02 – Fichero o directorio
En esta nueva versión, comprobaremos si el fichero es un directorio o un fichero regular, indicando en cada caso con un mensaje el tipo de fichero que es.
Si es un fichero regular, mostraremos un mensaje indicando el tipo de fichero que es y la información extendida del mismo.
Si es un directorio, mostraremos un mensaje indicando que es un directorio y mostraremos información extendida del directorio, no de su contenido, e información resumida de ocupación del directorio en formato comprensible por humanos.
Dejar una respuesta