실행 중인 프로세스의 출력을 비교하는 방법은 무엇입니까?

실행 중인 프로세스의 출력을 비교하는 방법은 무엇입니까?

벤치마크를 실행 중입니다.gem5 시뮬레이터, 실행되는 동안 출력을 터미널에 계속 인쇄합니다. 나는 이미 동일한 벤치마크의 샘플 실행을텍스트 파일.

이제 콘솔에 인쇄되는 출력 스트림을 이전 골든 런의 텍스트 파일과 비교하고 싶습니다. 텍스트 파일과 출력 결과에 차이가 있는 경우 시뮬레이션을 자동으로 종료해야 합니다.

벤치마크를 실행하는 데 많은 시간이 걸립니다. 나는 현재 실행의 첫 번째 오류에만 관심이 있으므로 두 출력을 비교하기 위해 실행이 완료될 때까지 기다리는 시간을 절약할 수 있습니다.

답변1

나는 출력을 비교하는 적절한 방법을 찾는 데 조금 더 당황하지 않을 수 없었습니다.실행 중인 프로세스(터미널에서) 언급한 대로 "골든 런" 파일에 대해.

실행 중인 프로세스의 출력을 잡는 방법

script옵션 과 함께 명령 을 사용했습니다 -f. 현재(텍스트) 터미널 내용을 파일에 씁니다. 옵션 -f은 터미널에 대한 각 쓰기 이벤트의 출력 파일을 업데이트하는 것입니다. 스크립트 명령은 터미널 창에서 일어나는 모든 일을 기록하기 위해 만들어졌습니다.
아래 스크립트는 이 출력을 주기적으로 가져옵니다.

이 스크립트의 기능

터미널 창에서 스크립트를 실행하면 명령으로 시작되는 두 번째 터미널 창이 열립니다 script -f. 이 (두 번째) 터미널 창에서 명령을 실행하여 벤치마크 프로세스를 시작해야 합니다. 이 벤치마크 프로세스에서 결과가 생성되는 동안 이러한 결과는 "골든 런"과 주기적으로(2초마다) 비교됩니다. 차이가 발생하면 다른 출력이 "기본"(첫 번째) 터미널에 표시되고 스크립트가 종료됩니다. 다음 형식으로 줄이 나타납니다.

error: ('Solutions: 13.811084', 'Solutions: 13.811084 aap noot mies')

explanation:

error: (<golden_run_result>, <current_differing_output>)

이 출력 후에는 두 번째 창을 안전하게 닫고 테스트를 실행할 수 있습니다.

사용하는 방법

  • 아래 스크립트를 빈 파일에 복사하세요.
    "골든 런" 파일을 볼 때 첫 번째 섹션(실제 테스트 시작 전)은 관련이 없으며 시스템마다 다를 수 있습니다. 따라서 실제 출력이 시작되는 라인을 정의해야 합니다. 귀하의 경우에는 다음과 같이 설정했습니다.

    first_line = "**** REAL SIMULATION ****"
    

    필요한 경우 변경하십시오.

  • "golden run" 파일의 경로를 설정하십시오.
  • 스크립트를 로 저장하고 compare.py다음 명령으로 실행합니다.

    python3 /path/to/compare.py
    

    `

  • 두 번째 창이 열리면서 다음과 같이 말합니다.Script started, the file is named </path/to/file>
  • 이 두 번째 창에서 벤치마크 테스트를 실행하면 첫 번째 창에 첫 번째 다른 결과가 나타납니다.

여기에 이미지 설명을 입력하세요

내가 테스트한 방법

나는 당신의 골든 런의 편집된 버전의 줄을 하나씩 인쇄하는 작은 프로그램을 만들었습니다. 나는 그것을 원본 "golden run" 파일과 비교하는 스크립트를 만들었습니다.

스크립트:

#!/usr/bin/env python3

import subprocess
import os
import time

home = os.environ["HOME"]

# files / first_line; edit if necessaary
golden_run = "/home/jacob/Bureaublad/log_example"
first_line = "**** REAL SIMULATION ****"

# don't change anything below
typescript_outputfile = home+"/"+"scriptlog.txt"
# commands
startup_command = "gnome-terminal -x script -f "+typescript_outputfile
clean_textcommand = "col -bp <"+typescript_outputfile+" | less -R"
# remove old outputfile
try:
    os.remove(typescript_outputfile)
except Exception:
    pass
# initiate typescript
subprocess.Popen(["/bin/bash", "-c", startup_command])
time.sleep(1)
# read golden run
with open(golden_run) as src:
    original = src.read()
orig_section = original[original.find(first_line):]
# read last output of current results so far
def get_last():
    read = subprocess.check_output(["/bin/bash", "-c", clean_textcommand]).decode("utf-8")
    if not first_line+"\n" in read:
        return "Waiting for first line"
    else:
        return read[read.find(first_line):]
    with open(typescript_outputfile, "wt") as clear:
        clear.write("\n")
# loop
while True:
    current = get_last()
    if current == "\n":
        pass
    else:
        if not current in orig_section and current != "Waiting for first line":
            orig = orig_section.split("\n")
            breakpoint = current.split("\n")
            diff = [(orig[i], breakpoint[i]) for i in range(len(breakpoint)) \
                    if not orig[i] == breakpoint[i]]
            print("error: "+str(diff[0]))
            break
        else:
            pass
    time.sleep(5)

답변2

유틸리티를 사용할 수 있습니다 diff.

당신이 가지고 있다고 가정당신의골든 파일, 그리고또 다른내가 변했다고.

귀하의 프로그램이 실행되고 있지 않기 때문에 다음 시뮬레이션을 작성했습니다.

#!/bin/bash
    while read -r line; do
        echo "$line";
        sleep 1;
    done < bad_file

그것은에서 읽습니다또 다른파일(bad_file)을 저장하고 매초마다 한 줄씩 출력합니다.

이제 이 스크립트를 실행하고 출력을 log파일로 리디렉션합니다.

$ simulate > log &

또한 나는 검사기 스크립트를 작성했습니다.

#!/bin/bash

helper(){
    echo "This script takes two file pathes as arguments."
    echo "$0 path/to/file1 path/to/file2"
}

validate_input(){
    if [[ $# != 2 ]]; then 
        helper
        exit 1
    fi

    if [[ ! -f "$1" ]]; then
        echo "$1" file is not exist.
        helper
        exit 1
    fi
    if [[ ! -f "$2" ]]; then
        echo "$2" file is not exist.
        helper
        exit 1
    fi
}

diff_files(){
# As input takes two file and check
# difference between files. Only checks
# number of lines you have right now in
# your $2 file, and compare it with exactly
# the same number of lines in $1
    diff -q -a -w <(tail -n+"$ULINES" $1 | head -n "$CURR_LINE") <(tail -n+"$ULINES" $2 | head -n "$CURR_LINE")
}

get_curr_lines(){
# count of lines currenly have minus ULINES
    echo "$[$(cat $1 | wc -l) - $ULINES]"
}

print_diff_lines(){
    diff -a -w --unchanged-line-format="" --new-line-format=":%dn: %L" "$1" "$2" | grep -o ":[0-9]*:" | tr -d ":"
}

ULINES=15 # count of first unused lines. How many first lines to ignore

validate_input "$1" "$2"
CURR_LINE=$(get_curr_lines "$2") # count of lines currenly have minus ULINES

if [[ $CURR_LINE < 0 ]];then
    exit 0
fi

IS_DIFF=$(diff_files "$1" "$2")
if [[ -z "$IS_DIFF" ]];then
    echo "Do nothing if they are the same"
else
    echo "Do something if files already different"
    echo "Line number: " `print_diff_lines "$1" "$2"`
fi

실행 가능하게 만드는 것을 잊지 마십시오 chmod +x checker.sh.

이 스크립트는 두 개의 인수를 사용합니다. 첫 번째 인수는 골든 파일의 경로이고, 두 번째 인수는 로그 파일의 경로입니다.

$ ./checker.sh path_to_golden path_to_log

이 검사기는 현재 log파일에 있는 줄 수를 계산하고 이를 golden_file.

매초마다 검사기를 실행하고 필요한 경우 kill 명령을 실행합니다.

원한다면 checker.sh매초 실행되도록 bash 함수를 작성할 수 있습니다.

$ chk_every() { while true; do ./checker.sh $1 $2; sleep 1; done; }

diff에 대한 이전 답변의 일부

텍스트 파일로 한 줄씩 비교할 수 있습니다

에서man diff

NAME
   diff - compare files line by line

   -a, --text
          treat all files as text

   -q, --brief
          report only when files differ

   -y, --side-by-side
          output in two columns

파일을 비교하면:

$ diff -a <(tail -n+15 file1) <(tail -n+15 file2)

다음 출력이 표시됩니다.

2905c2905
< Solutions: 0.686669
---
> Solutions: 0.686670
2959c2959
< Solutions: 0.279124
---
> Solutions: 0.279125
3030c3030
< Solutions: 0.539016
---
> Solutions: 0.539017
3068c3068
< Solutions: 0.308278
---
> Solutions: 0.308279

서로 다른 선을 보여줍니다

그리고 여기에 마지막 명령이 있습니다. 처음 15줄을 확인하고 싶지 않다고 가정하겠습니다.

$ diff -y -a <(tail -n+15 file1) <(tail -n+15 file2)

두 열의 모든 차이점이 표시됩니다. 차이점이 있는지 알고 싶다면 다음을 사용하세요.

$ diff -q -a <(tail -n+15 file1) <(tail -n+15 file2)

파일이 동일하면 아무것도 인쇄되지 않습니다.

답변3

입력 데이터가 얼마나 복잡한지는 모르겠지만 awk입력되는 각 줄을 읽고 알려진 값과 비교하는 것과 같은 것을 사용할 수 있습니다.

$ for i in 1 2 3 4 5; do echo $i; sleep 1; done | \
  awk '{print "Out:", $0; fflush(); if ($1==2) exit(0)}'
Out: 1
Out: 2

이 경우에는 시간이 지연된 숫자 스트림을 입력하고 awk입력의 첫 번째 변수(오직여기서 변수)는 2와 같으며 종료되고 그렇게 하면 스트림이 정지됩니다.

관련 정보