如何反转 grep 返回的计数?

如何反转 grep 返回的计数?

我正在编写测试脚本。我希望在另一个测试时运行一个特定的测试才不是返回失败。这是我正在使用的基本测试,并将其分配给 shell 脚本变量:

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

如果是 GCC 4.8 或 Clang 3.2(或更高版本),则未定义行为清理程序可用,并且返回值为grep0。如果编译器缺乏支持,则该值不为 0。例如:

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

如果我尝试使用grep -v -c, then 线不匹配对“错误”进行计数,这有效地对预处理器转储的行进行了计数。所以我得到的结果是 248(无错误)和 1(有错误),但失败时我从未得到 0 值。

后来,为了可读性,我执行:

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

问题是我必须否定测试返回的计数grep -c error以保持可读性。也就是说,我必须将结果变成0(没有)或非0(有)。

在 C/C++ 中,我将执行相当于(注意!关于表达式):

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

如何反转从 返回的计数grep


Valgrind 测试有这个问题,因为我可以直接使用计数:

 HAVE_VALGRIND=`which valgrind | grep -i -c valgrind`

答案1

在这些情况下你可以直接检查cpp的返回值:

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

甚至

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

或者,回到你的问题的重点,否定比较的意义,即检查 cpp 的失败,与你给出的 C++ 示例非常相似,请使用!

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

可以使用类似的技术来设置 VALGRIND:

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

由于您了解 C++,因此您会熟悉&&||。它们在 shell 命令行上的工作原理类似。在上面,如果which valgrind > /dev/null成功,则将回显“1”。

相关内容