Comprobando el éxito de un comando en una instrucción bash `if `

Estoy tratando de automatizar nuestra copia de seguridad de la aplicación. Parte del proceso es verificar el estado de salida de egrep en una statement if :

 if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] || [ egrep -i -q "error|warning|fatal|missing|critical" "$File" ] then echo "testing" fi 

Esperaba que egrep testing porque el archivo existe y egrep devuelve éxito, pero en su lugar recibo un error:

 -bash: [: too many arguments 

Intenté con todo tipo de syntax: corchetes adicionales, comillas, etc. pero el error aún persiste.

Por favor, ayúdame a entender dónde me estoy equivocando.

Está cometiendo el error común de suponer que [ es parte de la syntax de la sentencia if . No lo es; la syntax 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 comunes que usamos es [ que es un alias para la test comando. Es un comando simple para comparar cadenas, números y archivos. Acepta una combinación bastante estrecha de argumentos, y tiende a generar mensajes de error confusos y engañosos si no le pasa los argumentos esperados. (O más bien, los mensajes de error son adecuados y útiles una vez que te acostumbras, pero se los malinterpreta fácilmente si no los usas).

Aquí, quiere 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, el command puede ser una interconexión o una lista de comandos; luego, el código de salida del comando final es el estado que se examinará, de forma 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 que un solo comando en la statement if (aunque no es desconocido, ¡su statement compuesta con || es un buen ejemplo!)

Las razones históricas para test como un fregadero de cocina general de cosas que los autores no quisieron hacer parte de la syntax de if es uno de los diseños menos atractivos del shell original de Bourne. Bash y zsh ofrecen alternativas que son menos difíciles de manejar (como los [[ dobles corchetes en bash), y por supuesto, la test POSIX es mucho más afable que la creación original de los Laboratorios Bell.

Esto funciona: ponga su egrep en “$ ()”, elimine -q y haga una comparación de cadenas:

 if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] || [ "$(egrep -i 'error|warning|fatal|missing|critical' $File)" != "" ]; then echo "testing"; fi