출력에 영향을 주지 않고 stdout에서 문자열의 존재를 어떻게 감지할 수 있습니까? [복사]

출력에 영향을 주지 않고 stdout에서 문자열의 존재를 어떻게 감지할 수 있습니까? [복사]

my_program진단 메시지를 stdout으로 인쇄라는 프로그램이 있습니다 .

진단 메시지에 문자열이 포함되어 있는지 확인 "TEST FAILURE"하고, 그렇다면 프로그램이 완료된 후 일부 명령을 실행하고 싶습니다.

내가 찾은 가장 가까운 대답은

if [ !my_program | grep "TEST FAILURE" ]
then
some_cmd
fi

그러나 이 방법을 사용하면 모든 진단 메시지가 무음 처리됩니다. 나는 여전히 메시지가 표준 출력에 표시되기를 원합니다. 어떤 사람들은 프로그램을 사용하지 않고 먼저 프로그램을 실행 grep한 다음 프로그램을 두 번째로 실행하고 파이핑할 것을 제안 grep하지만 내 프로그램은 실행하는 데 1시간이 걸리므로 큰 프로그램을 두 번 실행하는 것을 피하고 싶습니다.

어떤 아이디어가 있나요?

답변1

tee다음을 사용하여 명령 출력을 grep터미널 로 보낼 수 있습니다 /dev/tty.

# Note grep's stdout is redirected to /dev/null
# because we only care about its exit code
if echo foo | tee /dev/tty | grep foo > /dev/null; then
  echo OK
fi

POSIX에서디렉토리 구조 및 장치:

/dev/tty

각 프로세스에서 해당 프로세스의 프로세스 그룹과 연관된 제어 터미널에 대한 동의어(있는 경우)입니다. 출력이 리디렉션되는 방식에 관계없이 터미널에서 메시지를 쓰거나 터미널에서 데이터를 읽도록 하려는 프로그램이나 셸 프로세스에 유용합니다. 출력을 입력해야 하고 현재 사용 중인 터미널을 찾는 것이 어려울 때 출력 파일 이름이 필요한 응용 프로그램에서도 사용할 수 있습니다.

명령의 출력을 스크립트의 표준 출력(터미널이 아닐 수 있음)으로 리디렉션하려는 경우에는 도움이 되지 않습니다.

그러나 추가 처리를 위해 명령 출력을 저장할 수 있습니다.

# Save output in a variable (or a regular file, a named pipe, etc.)
output="$(echo foo)"

# Dump output to script's stdout
cat <<< "${output}"

# Check if output matches some pattern
if grep foo <<< "${output}" > /dev/null; then
  echo OK
fi

답변2

Bash에서 루프를 사용하면 문제를 해결할 수도 있습니다.

#!/bin/bash

flagfile=/tmp/flagfile.$$.something

my_program | while read line ; do 
    if echo "$line" | grep "TEST FAILURE" 
    then
        touch $flagfile
    else
        echo "$line"
    fi
done

if [ -f $flagfile ] ; then
    rm -f $flagfile
    some_cmd
fi

while 루프는 서브셸에서 실행되므로 플래그 변수를 사용할 수 없습니다.

관련 정보