簡體   English   中英

如何在Shell腳本中從測試的輸出中搜索“ ERROR”字符串?

[英]How to search for “ERROR” string from the output of the test in shell scripting?

我正在修改一個shell腳本,該腳本使用Makefile在不同的測試台上測試代碼,當前該shell腳本僅回顯SUCCESS和FAILURE,我想修改此shell腳本以搜索正在寫入到另一個文件的輸出跟蹤字符串。在同一位置調用Makefile,即trace.log。 如果它找到單詞“ ERROR”(這是一個跟蹤字符串),我希望測試說失敗

!/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
}

我沒有shell腳本方面的背景。 我通過搜索構造了解了這里寫的內容,但我仍然不了解for t in $tests工作方式以及sed作用。

我認為可以解決我的問題的是

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

研究了一下$? 和Shell腳本編寫,我知道這行不通,我應該怎么做才能實現這一目標?

for variable in one two threefor循環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
}

請注意在make之后添加了grep &&說“和”,然后說! 反轉grep的退出代碼(因此,如果grep找不到任何匹配項,則為true)。 -q抑制grep輸出的匹配項,並使其在找到第一個匹配項后立即停止搜索。

更切地講,我認為pushdpopd用於交互用途。 Shell腳本通常只是在子Shell中使用cd ,然后在子Shell完成后,您便回到了開始的目錄中。 但是在這里,可能需要更基本的重構。

對於稍微復雜但希望強大的重構,也許可以

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是測試的實際文件名,還是只是后綴(甚至是中間的某處)?

log=file.log
if grep ERRORS "$log" ; then echo BIG FAILURE ; fi

應該與任何外殼一起工作。

(感謝三人有用的評論)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM