bash: comando múltiplo em uma linha com código de saída diferente

0

Eu executo um comando bash de um código c++ usando a função system fornecida em código%. Minha pergunta não é sobre a implementação de cstdlib , mas a coisa que é relevante para a minha pergunta, é que eu tenho que executar vários comandos em uma linha.

Por exemplo, eu executo um script do gnuplot contido em outro diretório. Então meu comando é o seguinte:

cd some/path; gnuplot -e gnuplot_file.gp; cd - > /dev/NULL

Os dois comandos c++ são importantes por motivos pessoais. Eu também quero "ocultar" a saída em cd .

Aqui está a minha pergunta: como eu sei o status de saída do comando /dev/NULL ? Saber se falhou é o suficiente.

Meu problema é que atualmente recebo o status de saída do último comando, que é verdadeiro mesmo se o gnuplot falhou.

Eu sei que se eu usar gnuplot em vez de && , o último comando não será executado se o anterior falha e o status de saída seria falso. Mas eu preciso que o último comando seja executado ...

Qual é a solução alternativa?

    
por PinkFloyd 05.02.2016 / 09:11

4 respostas

6

Elimine o gnuplot em um subshell e então é o último comando executado. Você também não precisa mais do último cd porque a mudança de diretório no início da sub-camada afeta apenas o gnuplot , e assim o redirecionamento para /dev/null também é irrelevante.

( cd some/path; gnuplot -e gnuplot_file.gp )

Talvez você pretendesse redirecionar o /dev/null para o comando inteiro? (Isso não é o que você escreveu na sua pergunta).

( cd some/path; gnuplot -e gnuplot_file.gp ) >/dev/null

Por fim, minha preferência por um snippet como este seria executar o gnuplot somente se o cd inicial obtivesse êxito. Isso afetaria o status de saída, no qual você obteria um retorno falha se a alteração do diretório falhasse, mas provavelmente é um código mais seguro

( cd some/path && gnuplot -e gnuplot_file.gp ) >/dev/null
    
por 05.02.2016 / 12:41
2

Salve o valor de retorno em uma variável:

cd some/path; gnuplot -e gnuplot_file.gp; gnuplot_ret=$?; cd "$OLDPWD"; exit $gnuplot_ret

Outra maneira: executar em um subshell:

(cd some/path; gnuplot -e gnuplot_file.gp)

Como a alteração do diretório aconteceu em um subshell, isso não afeta seu shell atual e você não precisa cd de volta. E você obtém o status de saída de graça.

    
por 05.02.2016 / 09:21
2

Você pode capturar o código de saída em uma variável:

cd some/path; gnuplot -e gnuplot_file.gp ; a=$?

retornar ao diretório anterior (sem qualquer saída do console):

cd -- "$OLDPWD"

Imprimir código de saída

E, em seguida, imprima o código de saída capturado (linha completa):

cd some/path; gnuplot -e gnuplot_file.gp ; a=$?; cd -- "$OLDPWD"; echo "$a"

Se você precisar recriar um código de saída, há várias maneiras possíveis:

[ "x$a" == 'x0' ]
[ "$a" -eq 0 ]
[ ! "${a#0}" ]
[[ $a == 0 ]]
[[ $a -eq 0 ]]

É recomendável não usar "$ {a # 1}", pois um código de saída de erro pode ser qualquer número diferente de 1. Não é garantido que a seja 1 para um erro.

Ou, como é um número, se você aceitar usar uma solução aritmética (bash):

(( a == 0 ))
! (( a ))
(( ! a ))

Recriar o código de saída ..

A linha completa seria:

cd some/path; gnuplot -e gnuplot_file.gp ; a=$?; cd -- "$OLDPWD"; (( ! a ))

O código de saída será 0 ou 1, todos os erros serão reportados com um código de saída de 1.

Código de saída completo

Um exit "$a" é útil somente se for útil para finalizar a execução do script.
Entenda que isso preservará o código de saída real.

 cd some/path && gnuplot -e gnuplot_file.gp ; a=$?; cd -- "$OLDPWD"; exit "$a"

Um 'return' $ a '' pode ser útil se usado dentro de uma função.

function_gnuplot(){
    cd some/path && gnuplot -e gnuplot_file.gp ; a=$?
    cd -- "$OLDPWD"; return "$a"
}
    
por 05.02.2016 / 22:03
0

Você pode alterar o diretório em seu código antes de chamar o system

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define BUFFSIZE 1024

int main(int argc, char **argv) {
  char old_dir[BUFFSIZE];
  getcwd(old_dir, BUFFSIZE); 

  chdir("some/path");

  int retvalue=system("gnuplot -e gnuplot_file.gp");

  chdir(old_dir);

  if (retvalue == -4) {
    /* do something ... */
  }
}

Observe que essa solução é não segura em segmentos porque altera o diretório atual do processo.

    
por 05.02.2016 / 09:33