Estoy ejecutando un trabajo en Jenkins (Jenkins es una herramienta de integración continua de código abierto) ejecutando una lista de comandos de shell. Uno de los comandos es ejecutar un programa Java que realiza alguna validación de datos. Si se encuentra con una fecha no válida, el programa Java se cerrará con un código de salida distinto de cero para que Jenkins pueda descubrir que esta vez la compilación falla.
Desafortunadamente, el programa Java imprime demasiados registros en stdout y stderr, solo algunos de ellos son útiles. Como el programa Java no se puede modificar, decido filtrar la salida con grep . Así que escribí el shell como:
java -cp $CLASSPATH MetaValidatorMain | grep -v "useless keyword1"| grep -v "useless keyword2"Pero el problema es que, después de la ejecución de la línea de shell, el proceso principal (Jenkins) obtuvo el código de salida de grep en lugar de java , por lo que Jenkins no pudo determinar si la compilación fue exitosa.
También probé esto:
(java -cp $CLASSPATH MetaValidatorMain || exit 1) | grep -v "useless keyword1"| grep -v "useless keyword2"tampoco funcionó.
¿Alguien podría decirme cómo podría escribir la línea de Shell para filtrar la salida y obtener el código de salida correcto al mismo tiempo?
Gracias
Un poco largo, pero podría redirigir la salida del programa a un archivo, capturar el retorno y luego grep el archivo de salida para el contenido que desea:
java -cp $CLASSPATH MetaValidatorMain > /tmp/outfile.txt 2>&1 RETURN_CODE=$? grep -v "useless keyword1" /tmp/outfile | grep -v "useless keyword2" exit RETURN_CODEHay 3 formas de hacer esto. Sin embargo, su configuración actual debería funcionar. La razón aquí es que grep no coincidirá con nada si el comando falla, por lo que grep regresará con el estado 1 (a menos que el programa siempre muestre ese texto sin importar qué).
La primera forma es establecer la opción pipefail . Este es el más simple y lo que hace es básicamente establecer el estado de salida $? al código de salida del último programa para salir distinto de cero (o cero si todos salieron con éxito).
# false | true; echo $? 0 # set -o pipefail # false | true; echo $? 1 Bash también tiene una variable llamada $PIPESTATUS que contiene el estado de salida de todos los programas en el último comando.
# true | true; echo "${PIPESTATUS[@]}" 0 0 # false | true; echo "${PIPESTATUS[@]}" 1 0 # false | true; echo "${PIPESTATUS[0]}" 1 # true | false; echo "${PIPESTATUS[@]}" 0 1Puede usar el ejemplo del tercer comando para obtener el valor específico en la canalización que necesita.
Sin embargo, es posible que esta solución no esté disponible. Creo que $PIPESTATUS podría haberse agregado en una versión bastante reciente de bash, y es posible que su sistema operativo no lo tenga.
Esta es la más difícil de manejar de las soluciones. Ejecute cada comando por separado y capture el estado
# java -cp $CLASSPATH MetaValidatorMain > /tmp/outfile.txt 2>&1 # RETURN_CODE=$? # grep -v "useless keyword1" /tmp/outfile | grep -v "useless keyword2" # exit RETURN_CODE