Как инвертировать счет, возвращенный из grep?

Я работаю над тестовым скриптом. Я хочу, чтобы конкретный тест выполнялся, когда другой тест не возвращал сбой. Вот базовый тест, который я использую, и его назначение для переменной сценария оболочки:

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

Если его GCC 4.8 или Clang 3.2 (или выше), то дезинфицирующее средство Undefined Behavior доступно, а значение, возвращаемое из grep равно 0. Если компилятору не хватает поддержки, то значение не равно 0. Например:

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

Если я пытаюсь использовать grep -v -c , то подсчитываются строки, не соответствующие «ошибке», что эффективно подсчитывает строки, сбрасываемые препроцессором. Поэтому я получаю результат 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` 

One Solution collect form web for “Как инвертировать счет, возвращенный из grep?”

В этих случаях вы можете напрямую проверить возвращаемое значение 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 ++, вы будете знакомы с && и || , Они работают аналогично командной строке оболочки. В приведенном выше which valgrind > /dev/null , если which valgrind > /dev/null будет успешным, тогда будет отображаться «1».

  • Как перечислять только файлы JPEG из корня ниже с помощью командной строки?
  • Скрипт сопоставляет буквенный шаблон по нескольким строкам?
  • Написание функции bash для автозагрузки скриптов Matlab
  • Перейти на один уровень от несуществующего пути
  • Поиск ключевого слова в файле PDF
  • regexp в ksh для расширений tgz, tar.tgz
  • for loop для запуска команды для всех файлов в папке
  • Поймать неожиданный ввод одиночного символа в bash
  • Возможно одновременное использование скобок (перестановки) и расширения массива?
  • bash, не используя ssh -i. Не удается найти каталог
  • Как извлечь дату и рассчитать, находится ли она в течение «х» дней с сегодняшнего дня?
  • Linux и Unix - лучшая ОС в мире.