Ctrl+ 와 같은 신호 키 C는 포 그라운드 프로세스 그룹 의 모든 프로세스에 신호를 보냅니다 .
일반적인 경우 프로세스 그룹은 파이프 라인입니다. 예를 들어에서에서 head <somefile | sort
실행중인 프로세스 head
와 실행중인 sort
프로세스는 셸과 동일한 프로세스 그룹에 있으므로 모두 신호를 수신합니다. 백그라운드 ( somecommand &
) 에서 작업을 실행할 때 해당 작업은 자체 프로세스 그룹에 있으므로 Ctrl+를 눌러도 C영향을 미치지 않습니다.
timeout
프로그램은 자체 프로세스 그룹에 자신을 배치합니다. 소스 코드에서 :
/* Ensure we're in our own group so all subprocesses can be killed.
Note we don't just put the child in a separate group as
then we would need to worry about foreground and background groups
and propagating signals between them. */
setpgid (0, 0);
시간 초과가 발생하면 해당 timeout
구성원이 속한 프로세스 그룹을 종료 하는 간단한 편의를 수행합니다. 자체 프로세스를 별도의 프로세스 그룹에 넣었으므로 상위 프로세스는 그룹에 없습니다. 여기에서 프로세스 그룹을 사용하면 하위 애플리케이션이 여러 프로세스로 분기되는 경우 모든 프로세스가 신호를 수신하게됩니다.
timeout
명령 행 에서 직접 실행 하고 Ctrl+ C를 누르면 결과 SIGINT가 timeout
하위 프로세스에 의해 수신 되지만 timeout
상위 프로세스 인 대화식 쉘에서는 수신 되지 않습니다 . 때 timeout
스크립트에서 호출되는 스크립트를 실행에만 쉘은 신호를 수신 : timeout
그것은 다른 프로세스 그룹이기 때문에 그것을 얻을하지 않습니다.
trap
내장 스크립트를 사용하여 쉘 스크립트에서 신호 핸들러를 설정할 수 있습니다 . 불행히도 그렇게 간단하지 않습니다. 이걸 고려하세요:
#!/bin/sh
trap 'echo Interrupted at $(date)' INT
date
timeout 5 sleep 10
date
2 초 후에 Ctrl+ 를 누르면 C여전히 5 초 동안 대기 한 다음 "Interrupted"메시지를 인쇄합니다. 포 그라운드 작업이 활성화되어있는 동안 쉘이 트랩 코드를 실행하지 못하게하기 때문입니다.
이를 해결하려면 백그라운드에서 작업을 실행하십시오. 신호 처리기에서 호출 kill
하여 신호를 timeout
프로세스 그룹 에 릴레이합니다 .
#!/bin/sh
trap 'kill -INT -$pid' INT
timeout 5 sleep 10 &
pid=$!
wait $pid
bg
offg
명령 을 주면 계속 실행됩니다 . 어쨌든, 첫 번째와 3d 예제 사이에 차이점이 있습니까?