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 루프는 서브셸에서 실행되므로 플래그 변수를 사용할 수 없습니다.