Comprobar el éxito de un comando en una declaración bash `if [ .. ]`

Resuelto Abhinandan Aithal asked hace 8 años • 1 respuestas

Estoy intentando automatizar la copia de seguridad de nuestra aplicación. Parte del proceso es verificar el estado de salida egrepen una ifdeclaració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 testingporque el archivo existe y egrepdevuelve é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.

Abhinandan Aithal avatar Apr 02 '16 15:04 Abhinandan Aithal
Aceptado

Está cometiendo el error común de suponer que eso [es parte de la ifsintaxis de la declaración. No lo es; la sintaxis de ifes 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 commandmensajes 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, commandpuede ser una canalización o una lista de comandos; luego, el código de salida del comando final es el estado que ifse 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 ifdeclaració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 testen los argumentos egrep foo bar. Pero [sin opciones solo acepta un único argumento y luego verifica si ese argumento es la cadena vacía. ( egrepClaramente 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, testcomo fregadero general de cosas que los autores no querían que formaran parte de la sintaxis, ifes uno de los diseños menos atractivos del shell Bourne original. Bash y zshofrezca alternativas que sean menos difíciles de manejar (como los [[corchetes dobles en bash) y, por supuesto, POSIX testtiene mucho más carácter que la creación original de Bell Labs.

tripleee avatar Apr 02 '2016 09:04 tripleee