하위 파이프라인 프로세스의 상위 프로세스를 종료합니다.

하위 파이프라인 프로세스의 상위 프로세스를 종료합니다.

내가 하고 싶은 일을 보여주는 작은 스크립트가 있습니다.

#!/bin/bash
> z
tail -f z | grep 'd' &
echo $!

$!grep 프로세스의 PID를 제공합니다 . grep 프로세스와 동시에 tail 프로세스를 종료할 수 있기를 원합니다. 이렇게 해도 kill "pid of grep"tail 프로세스가 종료되지는 않습니다. 도 아니고 killall grep. 사용해도 되지만 killall tail위험할 것 같아요.

답변1

명령을 괄호로 묶습니다.

( tail -f z | grep 'd' ) &
kill -- -$!

이렇게 하면 전체 하위 프로세스가 종료됩니다.

여기서는 종료할 음수 PID를 지정하여 전체 프로세스 그룹을 종료합니다. 바라보다 man 1 kill:

음수 PID 값은 전체 프로세스 그룹을 선택하는 데 사용될 수 있습니다. ps 명령 출력의 PGID 열을 참조하세요.

또는 man 2 kill:

pid가 -1보다 작으면 ID가 -pid인 프로세스 그룹의 모든 프로세스에 sig가 전송됩니다.

그러나 kill -PID그것은 단지 작동합니다작업 제어가 활성화된 경우in bash(대화형 쉘의 기본값). 그렇지 않으면 하위 프로세스에 전용 프로세스 그룹이 없고 kill 명령이 실패합니다.kill: (-PID) - No such process

이 문제를 해결하려면 bash( ) set -m에서 작업 제어를 활성화하거나pkill -P $!

답변2

나는 이것을 시도했지만 그것은 나에게 효과가 없습니다

( tail -f z | grep 'd' ) &
kill -- -$!

이름 없는 파이프 대신 이름 있는 파이프를 사용합니다.

rm -f tailfifo; mkfifo tailfifo
tail -n 0 -f mylog.log >tailfifo &
TAIL_PID=$!
grep --line-buffered someword <tailfifo >outputfile &
GREP_PID=$!
# .. ..
kill $TAIL_PID
kill $GREP_PID

답변3

시한의 대답 비대화형 sh(대시)에서는 작동하지 않습니다. 를 사용하면 ()프로세스 그룹이 생성되지 않으므로 sh -c '(sleep 6m | sleep 8m) & kill -- -$!'아무런 효과가 없습니다.

ps --no-headers --format pgid:1 $! 그러나 여전히 전체 파이프라인의 pgid를 찾아 종료하는 데 사용할 수 있습니다 .

sleep 6m | sleep 8m &
pgid=`ps -ho $!`
kill -- -$pgid

게다가 ()이를 파이프라인에서 사용하면 셸이 프로세스 그룹을 생성할 수 없게 됩니다.

pgid() {
    ps --no-headers --format pgid:1 $1
}

while true
do nc $ip $port
done | str2str -out tcpsvr://:5566 &
echo `pgid $!` == $$
wait

관련 정보