lunes, 6 de marzo de 2017

Combinando expresiones

También es posible combinar expresiones para crear evaluaciones más complejas. Las expresiones se combinan usando operadores lógicos. Los vimos en el Capítulo 17, cuando aprendimos el comando find. Hay tres operaciones lógicas para test y [[ ]]. Son AND, OR y NOT. test y [[ ]] usan operadores diferentes para representar estas operaciones:

Tabla 27-4: Operadores lógicos
Operación test [[ ]] y (( ))
AND -a &&
OR - o | |
NOT ! !

Aquí tenemos un ejemplo de una operación AND. El siguiente script determina si un entero está dentro de un rango de valores:

#!/bin/bash

# test-integer3: determine if an integer is within a
# specified range of values.

MIN_VAL=1
MAX_VAL=100

INT=50

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
     if [[ INT -ge MIN_VAL && INT -le MAX_VAL ]]; then
          echo "$INT is within $MIN_VAL to $MAX_VAL."
     else
          echo "$INT is out of range."
     fi
else
        echo "INT is not an integer." >&2
        exit 1
fi

En este script, determinamos si el valor del entero INT se encuentra entre los valores MIN_VAL y MAX_VAL. Esto se realiza con un sólo uso de [[ ]], que incluye dos expresiones separadas por el operador &&. Podríamos haber realizado este código usando test:

     if [ $INT -ge $MIN_VAL -a $INT -le $MAX_VAL ]; then
          echo "$INT is within $MIN_VAL to $MAX_VAL."
     else
          echo "$INT is out of range."
     fi

El operador de negación ! invierte el resultado de una expresión. Devuelve verdadero si una expresión es falsa, y devuelve falso si una expresión es verdadera. En el siguiente script, modificamos la lógica de nuestra evaluación para encontrar valores de INT que están fuera del rango especificado:

#!/bin/bash

# test-integer4: determine if an integer is outside a
# specified range of values.

MIN_VAL=1
MAX_VAL=100

INT=50

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
     if [[ ! (INT -ge MIN_VAL && INT -le MAX_VAL) ]]; then
          echo "$INT is outside $MIN_VAL to $MAX_VAL."
     else
          echo "$INT is in range."
     fi
else
        echo "INT is not an integer." >&2
        exit 1
fi

También incluimos paréntesis alrededor de la expresión, para agruparla. Si no se incluyeran, la negación sólo se aplicaría a la primera expresión y no a la combinación de las dos. Para escribir el código con test lo haríamos de esta forma:

if [ ! \( $INT -ge $MIN_VAL -a $INT -le $MAX_VAL \) ]; then
    echo "$INT is outside $MIN_VAL to $MAX_VAL."
else
    echo "$INT is in range."
fi

Como todas las expresiones y operaciones usadas con test se tratan como argumentos de comandos por el shell (al contrario de [[ ]] y (( )) ), los caracteres que tienen un significado especial para bash, como <, >, (, y ), deben ser entrecomillados o escapados.

Viendo que test y [[ ]] hacen más o menos lo mismo, ¿cuál es mejor? test es tradicional (y parte de POSIX), mientras que [[ ]] es especifico para bash. Es importante saber como usar test, ya que su uso está muy expandido, pero [[ ]] es claramente más útil y fácil para escribir código.

No hay comentarios:

Publicar un comentario