Как найти строку «ОШИБКА» из результатов теста в сценариях оболочки? - PullRequest
0 голосов
/ 30 января 2019

Я изменяю сценарий оболочки, который использует Makefile для тестирования кода в разных тестовых стендах, в настоящее время сценарий оболочки только выводит SUCCESS и FAILURE, я хочу изменить этот сценарий оболочки для поиска по строкам выходной трассировки, которые записываются вдругой файл в том же месте, где вызывается Makefile, а именно trace.log.Если он находит слово «ОШИБКА» (который является строкой трассировки), я хочу, чтобы в тесте было указано НЕИСПРАВНОСТЬ

!/usr/bin/env bash
#set -e

BASEDIR=$(pwd)
REPOROOT=`git rev-parse --show-toplevel`


RED="`tput setaf 1`"
GREEN="`tput setaf 2`"
BLUE="`tput setaf 4`"
NORM="`tput sgr0`"

Test() {
    pushd ${REPOROOT}/rr/Fmda/body > /dev/null
    tests=`find . -type f | grep "test.xml" | sed "s/test\.xml//"`
    for t in $tests; do
      testname=`echo $t | sed "s/\.\///" | sed "s/\/test\///"`
      echo -e "${BLUE}EXECUTING $testname TEST${NORM}"
      pushd $t > /dev/null
      make test_svp
      if [ $? -eq 0 ]; then
        echo -e "${GREEN}SUCCESS IN $testname TEST MOVING ON!${NORM}"
      else
        echo "${RED}FAILURE IN $testname TEST${NORM}"
        exit 1
      fi
      popd > /dev/null
     done
     popd > /dev/null
}

У меня нет фона в сценариях оболочки.Я понял, что здесь написано, прибегая к помощи конструкций, но все же я не понимал, как работает for t in $tests и что делает sed.

Из того, что я думал, будет работать для моей проблемы:

error=trace.log|grep "ERROR"
if [ $? -eq 0] && [ !error ]; then 

Изучив немного о $? и сценариях оболочки, я знаю, что это не сработает, что мне нужно сделать, чтобы достичьэта вещь?

Ответы [ 2 ]

0 голосов
/ 30 января 2019

for loop for variable in one two three запустит тело цикла с $variable, установленным на one на первой итерации, two на следующей и затем на three.Когда цикл завершается, переменная сохраняет последнее значение, которое она имела в цикле.

sed - это отдельный язык сценариев, хотя обычно он используется только для тривиальных подстановок строк.Сценарий sed s/regex/replacement/g заменяет каждое совпадение регулярного выражения статической строкой replacement в обрабатываемом им файле (ах).(При отсутствии флага /g будет заменено только первое вхождение в каждой строке ввода.)

Как правило, сценарии должны проверять состояние выхода из команды, а не grep для читаемых человеком строк.Команда make уже иллюстрирует это, хотя она не совсем идиоматична.

Кстати, shebang в первой строке должен начинаться именно с двух символов #!

Вот рефакторинг с комментариями.

#!/usr/bin/env bash
#set -e

# Use lower case for your private variables
# BASEDIR was never used for anything
# Consistently use modern command substitution syntax
reporoot=$(git rev-parse --show-toplevel)

RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
BLUE="$(tput setaf 4)"
NORM="$(tput sgr0)"

Test() {
    # Maybe don't pushd; see below
    # Quote the variable properly 
    pushd "$reporoot/rr/Fmda/body" > /dev/null
    # Refactor to avoid useless use of grep
    tests=$(find . -type f | sed -n "s/test\.xml//p")
    for t in $tests; do
      # Proper quoting; refactor to a single sed script
      # Fix sed syntax error (too many slashes)
      testname=$(echo "$t" | sed "s/\.\//;s%/test/%%")
      echo -e "${BLUE}EXECUTING $testname TEST${NORM}"
      pushd "$t" > /dev/null
      # Use "if" like it was meant to
      # Add grep condition
      if make test_svp && ! grep -q "ERROR" trace.log; then
        echo -e "${GREEN}SUCCESS IN $testname TEST MOVING ON!${NORM}"
      else
        echo "${RED}FAILURE IN $testname TEST${NORM}"
        exit 1
      fi
      popd >/dev/null
    done
    popd >/dev/null
}

Обратите внимание на добавление grep после make.&& говорит "и", а ! инвертирует код выхода из grep (так что это верно, если grep не может найти совпадения).-q подавляет вывод совпадений на grep и приводит к тому, что поиск прекращается, как только он находит первое совпадение.

Более тангенциально, я бы считал pushd и popd предназначенными дляинтерактивное использование.Сценарии оболочки, как правило, просто cd в подоболочке, а затем, когда она завершается, вы возвращаетесь в каталог, в котором вы начали.Но здесь может потребоваться более фундаментальный рефакторинг.

Для более сложного, но, надеюсь, надежного рефакторинга, возможно, сделайте

Test() {
    find "$reporoot/rr/Fmda/body" -name 'test.xml' \
        \( -execdir sh -c '
            # XXX TODO: maybe replace with parameter substitutions
            testname=$(echo "$1" | sed "s%/test\.xml$%%;s/\.\//;s%/test/%%")
            echo -e "${BLUE}EXECUTING $testname TEST${NORM}"
            make test_svp &&
            ! grep -q "ERROR" trace.log &&
            echo -e "${GREEN}SUCCESS IN $testname TEST MOVING ON!${NORM}" ||
            { 
              echo "${RED}FAILURE IN $testname TEST${NORM}"
              exit 1; }' _ {} \; -o -quit \)
}

... хотя предикат -quit оченьрасширение GNU find (stol ... польщено от здесь ).

Здесь есть некоторые предположения относительно имен тестовых файлов, которые могут быть неверными.Является ли test.xml фактическим именем файла теста или просто суффиксом (или даже где-то посередине)?

0 голосов
/ 30 января 2019
log=file.log
if grep ERRORS "$log" ; then echo BIG FAILURE ; fi

Должен работать с любой оболочкой.

(Спасибо за три полезных комментария)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...