sed가 문자열을 찾으면 꼬리를 멈추는 방법은 무엇입니까? [복사]

sed가 문자열을 찾으면 꼬리를 멈추는 방법은 무엇입니까? [복사]

tail모든 줄이 다른 파일에 기록될 때까지 일치하는 항목을 찾은 후 명령을 종료하고 싶습니다 .

tail -f logfile | sed '/special string/q'  | tee output.txt

Output.txt에는 특수 문자열이 발견될 때까지 줄이 포함됩니다. 그런데 문제는 그 후에 tail명령을 종료하고 싶다는 것입니다 .

답변1

명시적으로 죽여야 합니다.

seq 1 10 > file
tail -f file | { sed /7/q; pkill -PIPE -xg0 tail; } | tee output

pkill -PIPE -xg0 tail방법

우리와 동일한 프로세스 그룹에 속한 SIGPIPE프로세스에 신호를 보냅니다 .tail

tail이는 동일한 프로세스 그룹에서 다른 프로세스가 실행되고 있지 않다고 가정합니다. 명령이 대화형 터미널(작업 제어가 포함된 셸)에서 실행되는 경우 각 파이프가 자체 프로세스 그룹(작업이라고도 함)에서 실행되므로 안전해야 합니다. 작업 제어가 없는 셸(예: 스크립트)에서는 작업 제어가 명시적으로 켜져 있는 별도의 셸에 파이프를 래핑할 수 있습니다.

sh -mc 'tail -f file | { sed /7/q; pkill -PIPE -xg0 tail; }' | tee output

하지만 GNU tail은 스스로 죽을 것입니다.

bash 및 coreutils와 함께 Linux 상자를 사용하는 경우 모든 것이 정상이며 아무것도 필요하지 않으며 자동으로 kill종료 tail됩니다.

debian$ tail -f file | sed /2/q
1
2
debian$ # WOW!

tail이는 GNU coreutils가 표준 출력이 여전히 유효한지 확인하기 위해 영리한 트릭을 사용하기 때문입니다.쓰기 가능: "준비"에 대한 폴링 중입니다.읽다"오류가 발생하면 마치 파이프의 다른 쪽 끝이 닫힌 것처럼 파이프의 쓰기 끝에서만 발생하는 조건입니다. 이 경우 tail신호로 간단히 자살할 수 있습니다 SIGPIPE. 참조소스 코드:

  FD_SET (STDOUT_FILENO, &rfd);

  /* readable event on STDOUT is equivalent to POLLERR,
     and implies an error condition on output like broken pipe.  */
  if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
    die_pipe ();

[실제로 다른 시스템에서 이를 수행 POLLHUP하거나 대체할 수 있지만 실제로는 중요하지 않습니다.]POLLHUP|POLLINPOLLERR

GNU tail은 소켓이나 tty가 아닌 파이프에서만 이 작업을 수행합니다. 즉, Knee Unix 도메인 소켓을 사용하여 "파이프"를 구현하는 ksh93에서는 작동하지 않습니다.

또한 (내가 아는 한) GNU만이 tail이 작업을 수행하며 버전에서만 가능합니다.8.28; Linux에서도 busybox tail에는 없습니다.

이는 사용 tail -f | quit_at_some_point(여기에 있는 많은 답변으로 판단)이 여전히 매우 부수적이며 실제로 끝나지 않을 수 있음을 의미합니다.

답변2

다음을 고려하면 logfile:

one
two
three
special string
four

그리고 다음 명령

$ tail -f logfile | sed '/special string/q'  | tee output.txt

다음과 같은 결과가 나타납니다.

one
two
three
special string

그런 다음둘 다 tail성공적 으로 sed종료되었습니다. 따라서 귀하의 예(적어도 내 컴퓨터에서는)가 귀하가 설명하는 것과 정확히 일치합니다. 이를 추가로 확인하기 위해 다음 문서가 제공됩니다.

one
two
three
four

출력이 나오지 않고 명령이 중단되어 기다리고 있습니다 . 그런 다음 별도의 터미널에서 명령을 사용하여 추가 special string하면 원래 명령이 다시 성공적으로 종료됩니다.echo special string >> logfile

그럼 모든 게 정상으로 보이는 거죠, 그렇죠? 그렇지 않다면, 기대하는 바를 알려주십시오. 어쨌든, 앞으로 사용할 멋진 새 트릭을 배워주셔서 감사합니다!

관련 정보