특정 문자열이 관찰 될 때까지 명령의 출력을 "보고"종료


29

특정 문자열이 관찰 될 때까지 명령의 출력을 프로그래밍 방식으로보고 종료하는 방법을 찾고 있습니다. 이것은 질문 과 매우 유사 하지만 파일을 꼬리 대신하는 대신 명령을 '꼬리'하고 싶습니다.

다음과 같은 것 :

watch -n1 my_cmd | grep -m 1 "문자열 검색 중"

(그러나 이것은 나를 위해 작동하지 않습니다.)

업데이트 : 'my_cmd'는 텍스트를 지속적으로 출력하지 않지만 문자열을 찾을 때까지 반복적으로 호출해야한다는 것을 분명히해야합니다 (그래서 'watch'명령을 생각했습니다). 이와 관련하여 'my_cmd'는 ps, ls, lsof, last 등과 같은 다른 많은 유닉스 명령과 같습니다.


tail -f파일뿐만 아니라 프로그램 출력도 가능하다고 생각했을 것입니다 ... 내가 틀렸습니까?
Joanis

@Joanis. 당신 말이 맞지만, 제 경우에는 'my_cmd'가 지속적으로 출력을 생성하지 않고 반복적으로 호출되어야합니다 (대부분의 명령 : ps, ls, lsof 등)
gdw2

답변:


41

루프를 사용하십시오 :

until my_cmd | grep -m 1 "String Im Looking For"; do : ; done

대신 (또는 0.2)를 :사용 sleep 1하여 CPU를 완화 할 수 있습니다 .

grep이 명령 출력에서 ​​문자열을 찾을 때까지 루프가 실행됩니다. -m 1"하나의 일치로 충분"을 의미합니다. 즉, grep은 첫 번째 일치를 찾은 후 검색을 중지합니다.

grep -q첫 번째 일치 항목을 찾은 후 일치하는 줄을 인쇄하지 않고 종료되는 것을 사용할 수도 있습니다 .


이 명령에 대한 설명을 부탁드립니다.
Mark W

@MarkW : 업데이트되었습니다.
choroba

다른 사람이 언급 한 grep -q또 다른 옵션이다. 문자열을 찾은 후 grep이 종료됩니다.
일요일

이 명령은 해당 명령을 반복적으로 실행하므로 바람직하지 않을 수도 있습니다.
adrien

1
@A__ : OP의 "업데이트"에 명시된 바와 같이 바람직합니다.
choroba

11
watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
  • ! 명령 파이프 라인의 종료 코드를 무효화
  • grep -m 1 문자열이 발견되면 종료
  • watch -e 오류가 발생한 경우 반환

그러나 이것은 지금까지 버려진 일치하는 줄을 실제로 표시하도록 향상시킬 수 있습니다.


자세한 설명에 감사드립니다.하지만 저에게는 효과적이지 않습니다. 내 watch명령 (CentOS)에는 -e플래그가 없습니다 (실제로 중요하지 않아야 함). 그러나 더 중요한 것은 문자열이 발견되면 시계는 계속 실행되고 종료되지 않습니다. grep -m종료 할 때 킬만 종료 my_cmd하지만 종료 되지는 않는 것 같습니다 watch.
gdw2

"-e"플래그는 명령에 0과 다른 오류 코드가있는 경우 시계를 떠나기위한 것입니다. 현재 시계가 없기 때문에 플랫폼에서 계속하려고합니다. 어쨌든, 우분투 11.10 설치에서 모든 것이 정상입니다. 또한 매우 오래된 명령 줄 도구와 관련하여 Mac OSX에 문제가있는 경우가 있으며 현재까지 최신 소프트웨어를 얻기 위해 mac 포트를 사용하고 있습니다.
math

패턴이 발견되면 중지되지만, 그 때까지 출력이 표시되지 않습니다.
Mark

당신은 tee그 일을 할지 모르지만 이것은 잘못된 줄 바꿈을 소개합니다. 지금 우회하는 방법을 모르겠습니다.watch -n1 -e "! date | tee /dev/tty | grep --color -m 1 \"17\""
math

그래, 이것은 나를 위해 작동하지 않았다. watch현이 발견되면 조심스럽게 시청을 중단하지만 키를 누를 때까지 실제로 종료되지 않습니다. 너무 가까이
mlissner

8

stdout에 지속적으로 쓰는 프로그램이있는 경우 '단일 일치'옵션을 사용하여 grep하도록 파이프하면됩니다. grep이 일치하는 문자열을 찾으면 종료되고 grep으로 파이프되는 프로세스에서 stdout이 닫힙니다. 이 이벤트 프로세스가 다시 작성되는 한 자연스럽게 프로그램이 정상적으로 종료 되도록해야합니다 .

grep이 종료 된 후 닫힌 stdout에 쓰려고하면 프로세스에 SIGPIPE가 수신됩니다. 다음은 ping을 사용한 예입니다. 그렇지 않으면 무기한 실행됩니다.

$ ping superuser.com | grep -m 1 "icmp_seq"

이 명령은 처음으로 성공한 'pong'과 일치하고 다음 ping에 stdout에 쓰려고 시도 할 때 종료 됩니다.


하나,

프로세스가 stdout에 다시 쓰는 것이 항상 보장되는 것은 아니며 따라서 SIGPIPE가 발생하지 않을 수도 있습니다 (예 : 로그 파일의 테일링이 발생할 수 있음). 이 시나리오에서 내가 생각해 낸 최고의 솔루션은 파일에 쓰는 것입니다. 개선 할 수 있다고 생각되면 의견을 보내주십시오.

$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }

이것을 분해 :

  1. tail -f log_file & echo $! > pid-파일을 테일링하고 프로세스를 백그라운드에 첨부하고 PID ( $!)를 파일에 저장합니다. 대신 PID를 변수로 내보내려고했지만 여기와 PID가 다시 사용될 때 경쟁 조건이있는 것 같습니다.
  2. { ... ;}- 그룹 우리가 함께 (저장하고 변수를 재사용하는 데 도움이 때,하지만 그 부분의 작업을 얻을 수 없습니다) 현재의 상황을 유지하면서 출력을 grep으로하는 파이프 할 수 있습니다 그래서이 명령을
  3. | -왼쪽 stdout을 오른쪽 stdin으로 파이프
  4. grep -m1 "find_me" -대상 문자열을 찾으십시오
  5. && kill -9 $(cat pid)- 일치하는 문자열을 찾으면 종료 tail 프로세스 강제 종료 (SIGKILL) grep
  6. && rm pid -우리가 만든 파일을 제거

0
my_cmd | tail +1f | sed '/String Im Looking For/q'

경우 tail지원하지 않는 +1f구문을보십시오 tail -f -n +1. ( -n +1처음에 시작하도록 지시합니다. tail -f기본적으로 마지막 10 행의 출력으로 시작합니다.)


질문에 대한 내 업데이트를 참조하십시오.
gdw2

0

프로그램 호출 결과를 파일에 추가하십시오. 그런 다음 tail -f그 파일. 그런 식으로 작동해야합니다 ... 희망합니다.

해당 프로그램을 다시 시작하면 파일을 지우거나 약간의 횡설수설을 추가해야합니다. 그래서 바로 찾고 있던 것과 일치하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.