I'm working on a test script. I want a particular test to run when another test does not return a failure. Here's is the basic test I am using, and its assigned to a shell script variable:cpp -dM -fsanitize=undefined < /dev/null 2>&1 | grep -i -c errorIf its GCC 4.8 or Clang 3.2 (or above), then the Undefined Behavior sanitizer is available and the value returned from grep is 0. If the compiler lacks the support, then the value is non-0. For example:# Clang 3.1$ cpp -dM -fsanitize=undefined < /dev/nullclang: error: unsupported argument 'undefined' to option 'fsanitize='If I try to use grep -v -c, then lines not matching error are counted, which effectively counts the lines dumped by the preprocessor. So I get a result of 248 (no error) and 1 (with error), but I never get a 0-value on failure.Later, for readability, I perform:if [ $HAVE_UBSAN -ne 0 ]; then  export CXXFLAGS=-DNDEBUG -g2 -O2 -fsanitize=undefined $MY_CXXFLAGS  make ...  # Run self tests, scrape output for failuresfiThe problem is I must negate the count returned from the test grep -c error to maintain readability. That is, I must turn the result into 0 (does not have) or non-0 (does have).In C/C++, I would perform the equivalent to (notice the ! on the expression):!(`cpp -dM -fsanitize=undefined < /dev/null 2>&1 | grep -i -c error`)How do I invert the count returned from grep?I don't have this problem with the Valgrind test because I can use the count directly: HAVE_VALGRIND=`which valgrind | grep -i -c valgrind`
How to invert a count returned from grep?
bash;shell script;grep
In these cases you can check the return value of cpp directly:HAVE_UBSAN=$(cpp -dM -fsanitize=undefined < /dev/null > /dev/null 2>&1 && echo 1)if [ $HAVE_UBSAN = 1 ]. . .or evenif cpp -dM -fsanitize=undefined < /dev/null > /dev/null 2>&1then    export CXXFLAGS=-DNDEBUG -g2 -O2 -fsanitize=undefined $MY_CXXFLAGS    make ...    # Run self tests, scrape output for failuresfialternatively, and getting to the point of your question, to negate the sense of the comparison, that is, to check for failure of cpp, is very similar to the C++ example you gave, use !:    if ! cpp -dM -fsanitize=undefined < /dev/null > /dev/null 2>&1    then        echo 'NO sanitizer'    fiA similar technique can be used to set VALGRIND:    VALGRIND=$(which valgrind > /dev/null && echo 1)Since you know C++ you'll be familiar with && and ||.  They work similarly on the shell command line.  In the above, if which valgrind > /dev/null is successful, then 1 will be echoed.. 