Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

359
Visualizações
Filter output and obtain exit code at the same time of an program in Linux shell

I am running a job in Jenkins(Jenkins is an open source continuous integration tool) by executing a list of shell commands. One of the command is to run a Java program which does some data validation. If meets with invalid date, the Java program will exit with a none-zero exit code so that Jenkins can discover that this time the build fails.

Unfortunately the Java program prints too much log to stdout and stderr, only a few of them are useful. Since the Java program can not be modified, I decide to filter the output with grep. So I wrote the shell as:

java -cp $CLASSPATH MetaValidatorMain | grep -v "useless keyword1"| grep -v "useless keyword2"

But the problem is that, after the execution of the line of shell, the parent process(Jenkins) got exit code of grep indead of java, so that Jenkins could not determine whether the build was success.

I also tried this:

(java -cp $CLASSPATH MetaValidatorMain || exit 1) | grep -v "useless keyword1"| grep -v "useless keyword2"

also did not work.

Could anyone tell me how could I write the line of shell to filter output and obtain the right exit code at the same.

thx

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Bit of a long way round, but you could redirect the program output to a file, capture the return and then grep the output file for the content you want:

java -cp $CLASSPATH MetaValidatorMain > /tmp/outfile.txt 2>&1
RETURN_CODE=$?
grep -v "useless keyword1" /tmp/outfile | grep -v "useless keyword2"
exit RETURN_CODE
over 4 years ago · Santiago Trujillo Relatório

0

There are 3 ways of doing this. However your current setup should work. The reason here being that the grep won't match anything if the command fails, so grep will return with status 1 (unless the program always shows that text no matter what).

Pipefail

The first way is to set the pipefail option. This is the simplest and what it does is basically set the exit status $? to the exit code of the last program to exit non-zero (or zero if all exited successfully).

# false | true; echo $?
0
# set -o pipefail
# false | true; echo $?
1

$PIPESTATUS

Bash also has a variable called $PIPESTATUS which contains the exit status of all the programs in the last command.

# true | true; echo "${PIPESTATUS[@]}"
0 0
# false | true; echo "${PIPESTATUS[@]}"
1 0
# false | true; echo "${PIPESTATUS[0]}"
1
# true | false; echo "${PIPESTATUS[@]}"
0 1

You can use the 3rd command example to get the specific value in the pipeline that you need.

This solution might not be available though. I think $PIPESTATUS might have been added in a fairly recent version of bash, and your OS may not have it.

Separate executions

This is the most unwieldy of the solutions. Run each command separately and capture the status

# java -cp $CLASSPATH MetaValidatorMain > /tmp/outfile.txt 2>&1
# RETURN_CODE=$?
# grep -v "useless keyword1" /tmp/outfile | grep -v "useless keyword2"
# exit RETURN_CODE
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda