Como inverter uma contagem retornada do grep?

2

Estou trabalhando em um script de teste. Eu quero um teste específico para executar quando outro teste não retornar uma falha. Aqui está o teste básico que estou usando, e é atribuído a uma variável de script de shell:

cpp -dM -fsanitize=undefined < /dev/null 2>&1 | grep -i -c error

Se o seu GCC 4.8 ou Clang 3.2 (ou superior), o desinfetante de comportamento indefinido está disponível e o valor retornado de grep é 0. Se o compilador não tiver o suporte, então o valor é não-0. Por exemplo:

# Clang 3.1
$ cpp -dM -fsanitize=undefined < /dev/null
clang: error: unsupported argument 'undefined' to option 'fsanitize='

Se eu tento usar grep -v -c , então as linhas não correspondentes "error" são contadas, o que efetivamente conta as linhas descartadas pelo pré-processador. Então eu recebo um resultado de 248 (sem erro) e 1 (com erro), mas eu nunca obtenho um valor de 0 na falha.

Mais tarde, para legibilidade , eu executo:

if [ "$HAVE_UBSAN" -ne "0" ]; then
  export CXXFLAGS="-DNDEBUG -g2 -O2 -fsanitize=undefined $MY_CXXFLAGS"
  make ...
  # Run self tests, scrape output for failures
fi

O problema é que devo negar a contagem retornada do teste grep -c error para manter a legibilidade. Ou seja, devo transformar o resultado em 0 (não tem) ou não-0 (tem).

Em C / C ++, eu executaria o equivalente a (observe o ! na expressão):

!('cpp -dM -fsanitize=undefined < /dev/null 2>&1 | grep -i -c error')

Como inverto a contagem retornada de grep ?

Eu não tenho esse problema com o teste do Valgrind porque eu posso usar a contagem diretamente:

 HAVE_VALGRIND='which valgrind | grep -i -c valgrind'
    
por jww 27.10.2015 / 05:50

1 resposta

4

Nestes casos, você pode verificar o valor de retorno do cpp diretamente:

HAVE_UBSAN=$(cpp -dM -fsanitize=undefined < /dev/null > /dev/null 2>&1 && echo 1)
if [ "$HAVE_UBSAN" = 1 ]
. . .

ou até mesmo

if cpp -dM -fsanitize=undefined < /dev/null > /dev/null 2>&1
then
    export CXXFLAGS="-DNDEBUG -g2 -O2 -fsanitize=undefined $MY_CXXFLAGS"
    make ...
    # Run self tests, scrape output for failures
fi

alternativamente, e chegando ao ponto de sua pergunta, para negar o sentido da comparação, isto é, para verificar a falha do cpp, é muito semelhante ao exemplo de C ++ que você deu, use ! :

    if ! cpp -dM -fsanitize=undefined < /dev/null > /dev/null 2>&1
    then
        echo 'NO sanitizer'
    fi

Uma técnica semelhante pode ser usada para definir VALGRIND:

    VALGRIND=$(which valgrind > /dev/null && echo 1)

Como você conhece o C ++, você estará familiarizado com && e || . Eles funcionam de forma semelhante na linha de comando do shell. Acima, se which valgrind > /dev/null for bem sucedido, então "1" será ecoado ..

    
por 27.10.2015 / 06:26