내가 하고 싶은 일을 보여주는 작은 스크립트가 있습니다.
#!/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