Comprobar el éxito de un comando en una declaración bash `if [ .. ]`
Estoy intentando automatizar la copia de seguridad de nuestra aplicación. Parte del proceso es verificar el estado de salida egrep
en una if
declaración:
if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
[ egrep -i -q "error|warning|fatal|missing|critical" "$File" ]
then
echo "testing"
fi
Esperaba que saliera testing
porque el archivo existe y egrep
devuelve éxito, pero en su lugar aparece un error:
-bash: [: too many arguments
Intenté con todo tipo de sintaxis: corchetes adicionales, comillas, etc., pero el error persiste.
Por favor ayúdenme a comprender dónde me estoy equivocando.
Está cometiendo el error común de suponer que eso [
es parte de la if
sintaxis de la declaración. No lo es; la sintaxis de if
es simplemente
if command; then
: # ... things which should happen if command's result code was 0
else
: # ... things which should happen otherwise
fi
Uno de los command
mensajes de correo electrónico más comunes que utilizamos es [
cuál es un alias para el comando test
. Es un comando simple para comparar cadenas, números y archivos. Acepta una combinación bastante limitada de argumentos y tiende a generar mensajes de error confusos y engañosos si no le pasa los argumentos esperados. (O mejor dicho, los mensajes de error son adecuados y útiles una vez que te acostumbras, pero se malinterpretan fácilmente si no estás acostumbrado).
Aquí desea verificar el resultado del comando egrep
:
if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
egrep -i -q "error|warning|fatal|missing|critical" "$File"
then
echo "testing"
fi
En el caso general, command
puede ser una canalización o una lista de comandos; luego, el código de salida del comando final es el estado que if
se examinará, de manera similar a cómo el último comando en un script decide el estado de salida del script.
Estos comandos compuestos pueden ser arbitrariamente complejos, como
if read thing
case $thing in
'' | 'quit') false;;
*) true;;
esac
then ...
pero en la práctica, rara vez se ve más de un comando en la if
declaración (aunque no es algo inaudito; ¡la declaración compuesta con ||
es un buen ejemplo!)
Sólo para explicar esto,
if [ egrep foo bar ]
se está ejecutando [
también conocido como test
en los argumentos egrep foo bar
. Pero [
sin opciones solo acepta un único argumento y luego verifica si ese argumento es la cadena vacía. ( egrep
Claramente no es una cadena vacía. Citar aquí es opcional, pero quizás haría que fuera más fácil de ver:
if [ "egrep" ]; then
echo "yes, 'egrep' is not equal to ''"
fi
Obviamente, esto es una tontería por sí solo, pero es de esperar que funcione como un ejemplo ilustrativo).
Las razones históricas de que, test
como fregadero general de cosas que los autores no querían que formaran parte de la sintaxis, if
es uno de los diseños menos atractivos del shell Bourne original. Bash y zsh
ofrezca alternativas que sean menos difíciles de manejar (como los [[
corchetes dobles en bash) y, por supuesto, POSIX test
tiene mucho más carácter que la creación original de Bell Labs.