我正在编写测试脚本。我希望在另一个测试时运行一个特定的测试才不是返回失败。这是我正在使用的基本测试,并将其分配给 shell 脚本变量:
cpp -dM -fsanitize=undefined < /dev/null 2>&1 | grep -i -c error
如果是 GCC 4.8 或 Clang 3.2(或更高版本),则未定义行为清理程序可用,并且返回值为grep
0。如果编译器缺乏支持,则该值不为 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”。