Compra este Tutorial de Shell Scripting como PDF por sólo $5
Test es utilizado por prácticamente todos los scripts de shell escritos. Puede que no lo parezca, porquetest
no suele llamarse directamente. test
es más frecuentemente llamado como
if SPACE
Test is a simple but powerful comparison utility. For full details, run man test
en su sistema, pero aquí hay algunos usos y ejemplos típicos.
Test es más frecuentemente invocado indirectamente a través de las sentencias if
ywhile
. También es la razón por la que se encontrará con dificultades si crea un programa llamado test
e intenta ejecutarlo, ya que este shell builtin será llamado en lugar de su programa.
La sintaxis de if...then...else...
es:
if then # if-codeelse # else-codefi
if ; then # do somethingfi
También puedes usar el elif
, así:
if ; then echo "Something" elif ; then echo "Something else" else echo "None of the above"fi
Prueba el siguiente fragmento de código, antes de ejecutarlo establece la variable X a varios valores (prueba -1, 0, 1, hola, adiós, etc). Puede hacerlo de la siguiente manera (gracias a Dave por señalar la necesidad de exportar la variable, como se indica en Variables - Parte I.):
$ X=5$ export X$ ./test.sh ... output of test.sh ...$ X=hello$ ./test.sh ... output of test.sh ...$ X=test.sh$ ./test.sh ... output of test.sh ...
Luego inténtelo de nuevo, con $X
como el nombre de un archivo existente, como /etc/hosts
.
test.sh
Note que podemos usar el punto y coma (;
) para unir dos líneas. Esto se hace a menudo para ahorrar un poco de espacio en simples declaraciones if
.
La barra invertida (\
) tiene un propósito similar, pero opuesto: le dice al shell que no es el final de la línea, sino que la siguiente línea debe ser tratada como parte de la línea actual. Esto es útil para la legibilidad. Se acostumbra a sangrar la siguiente línea después de una barra invertida (\
) o un punto y coma (;
).
Por ejemplo, el punto y coma (;
) se utiliza a menudo así para unir las palabras clave if
y then
:
if ; then echo "X is a file which is newer than /etc/passwd"fi
mientras que la barra invertida (\
) se utiliza para dividir el comando de una sola línea a través de dos líneas en el archivo de script de shell, para fines de legibilidad:
&& \ echo "X is a file which is newer than /etc/passwd"
Como vemos en estos ejemplos, test
puede realizar muchas pruebas con números, cadenas y nombres de archivos.
Hay una forma más sencilla de escribir las sentencias if
: Los comandos &&
y ||
dan código para ejecutar si el resultado es verdadero, o falso, respectivamente.
Esta sintaxis es posible porque hay un archivo (o shell-builtin) llamado construir se recomienda para los bucles while y trivial sanitychecks con el que no desea distraer demasiado el lector.
Nótese que cuando se establece X a un valor no numérico, las primeras comparaciones dan como resultado el mensaje:
Esto se debe a que las comparaciones -lt, -gt, -le y -ge sólo están diseñadas para enteros, y no funcionan con cadenas. Las comparaciones de cadenas, como !=
, tratarán felizmente "5" como una cadena, pero no hay ninguna forma sensata de tratar "Hola" como un entero, por lo que las comparaciones de enteros se quejan.
Si quiere que su script de shell se comporte con más gracia, tendrá que comprobar el contenido de la variable antes de probarla - tal vez algo como esto:
De esta manera puede echo
un mensaje más significativo para el usuario, y salir con gracia. La variable $?
se explica en Variables - Parte II, y grep
es una bestia complicada, así que aquí va: grep
encuentra las líneas de texto que contienen dígitos (0-9) y posiblemente otros caracteres, por lo que el signo de intercalación (^
) en grep
encuentra sólo las líneas que no consisten sólo en números. A continuación, podemos tomar lo contrario (actuando sobre el fracaso, no sobre el éxito). ¿ok? El >/dev/null 2>&1
dirige cualquier salida o error al dispositivo especial "null", en lugar de ir a la pantalla del usuario.
Muchas gracias a Paul Schermerhorn por corregirme - esta página solía afirmar que grep -v
funcionaría, pero esto es claramente demasiado simplista.
Podemos usar test en bucles while de la siguiente manera:
test2.sh
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X echo "You said: $X"done
Este código seguirá pidiendo entrada hasta que se pulse RETURN (X es de longitud cero).Gracias a Justin Heath por señalar que el script no funcionaba - se me habían pasado las comillas alrededor de $X en el while
. Sin esas comillas, no hay nada que probar cuando $X está vacío.
Alexander Weber ha señalado que la ejecución de este script terminará de forma desordenada:
Esto se puede arreglar con otra prueba dentro del bucle:
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X if ; then echo "You said: $X" fidone
También hay que tener en cuenta que he utilizado dos sintaxis diferentes para las declaraciones if
en esta página. Estas son:
if then echo "X is less than zero"fi.......... and ........if ; then echo "You said: $X"fi
Debes tener una pausa entre la sentencia if
y la construcción then
. Puede ser un punto y coma o una línea nueva, no importa cuál, pero debe haber uno u otro entre la if
y la then
.Estaría bien decir simplemente:
if echo "You said: $X"
pero la then
y la fi
son absolutamente necesarias.
Atrás: Bucles Siguiente: Caso