배경
나는 기사를 읽었다우편 엽서신호 처리와 관련하여 SIGINT
대화형 및 비대화형 쉘 모두에서 선택하고 사용할 코드에서 신호를 올바르게 처리하는 방법을 여전히 이해하지 못합니다.
제 스크립트의 간단한 예를 들어보고 특정 부분에 대해 질문하겠습니다.
예
어디서나 구하고 사용할 수 있는 유용한 기능을 갖춘 스크립트가 있습니다.
/tmp/useful_functions.sh
#!/bin/bash
function example()
{
echo "Main script started"
# Make process run forever in the background.
( while sleep 1; do echo "Background script running"; done ) &
# Make subshell work for 10 seconds.
local output="$(sleep 10; echo "Subshell completed")"
echo "${output}"
# Kill the backgrounded process once the subshell has finished.
{ kill "${!}" && wait "${!}"; } &> /dev/null
echo "Main script completed"
}
테스트 1
사용하자예다른 스크립트 내에서 실행하세요.
/tmp/test.sh
#!/bin/bash
source /tmp/useful_functions.sh
example
이제 서브쉘이 작동하는 동안 실행 /tmp/test.sh
하고 눌러 보겠습니다. (서브쉘 = )Control-C
$(sleep 10; echo "Subshell completed")
왜냐하면. . . 결과Test 1
/tmp/test.sh
, example
, subshell
프로세스 background
가 종료되었습니다.
프롬프트가 새로운 입력을 기다리고 있습니다.
질문
SIGINT
프로세스 간 전송/처리/전파 순서는 무엇입니까?
(멘션은SIGINT
다음 주소로 보내야 합니다.모든 잠재 고객가장 안쪽 프로세스가 먼저 처리해야 합니다. )- 백그라운드 프로세스가 종료되는 이유는 무엇입니까?
테스트 2
사용하자예대화형 Bash에서 직접 실행:
...$ source /tmp/useful_functions.sh
...$ example
Control-C
서브쉘이 작동하면 다시 누르십시오.
(서브쉘 = $(sleep 10; echo "Subshell completed")
)
왜냐하면. . . 결과Test 2
example
프로세스가 subshell
종료되었지만 backgrounded
프로세스는 활성 상태로 유지됩니다. 프로세스의 출력이 인쇄되더라도
프롬프트는 여전히 새로운 입력을 기다리고 있습니다.backgrounded
질문
SIGINT
프로세스 간 전송/처리/전파 순서는 무엇입니까?- 백그라운드 프로세스가 지금 종료되지 않는 이유는 무엇입니까?
개선된 예
동작을 완전히 이해하지는 못하지만 Test 1
이 동작은 제가 기대하는 동작이며 대화형 Bash를 통해 이를 달성하고 싶습니다.
백그라운드 프로세스와 기존 서브셸을 감싸는 또 다른 서브셸을 만들고, 새 프로세스가 종료되면 백그라운드 프로세스와 기존 서브셸도 종료되기를 바라는 아이디어입니다.
/tmp/useful_functions.sh
#!/bin/bash
function example()
{
(
echo "Main script started"
# Make process run forever in the background.
( while sleep 1; do echo "Background script running"; done ) &
# Make subshell work for 10 seconds.
local output="$(sleep 10; echo "Subshell completed")"
echo "${output}"
# Kill the backgrounded process once the subshell has finished.
{ kill "${!}" && wait "${!}"; } &> /dev/null
echo "Main script completed"
)
}
중복된 결과Test 1
/tmp/test.sh
, example
및 프로세스가 outer subshell
종료 되었습니다. 프롬프트가 새로운 입력을 기다리고 있습니다.inner subshell
background
질문
SIGINT
프로세스 간 전송/처리/전파 순서는 무엇입니까?- 백그라운드 프로세스가 종료되는 이유는 무엇입니까?
중복된 결과Test 2
example
, outer subshell
, inner subshell
프로세스 background
가 종료되었습니다.
프롬프트가 새로운 입력을 기다리고 있습니다.
질문
SIGINT
프로세스 간 전송/처리/전파 순서는 무엇입니까?- 백그라운드 프로세스가 종료되는 이유는 무엇입니까?
질문
SIGINT
이 시점에서 저는 실제로 백그라운드 프로세스 후에 정리 작업을 해야 한다는 것과 이를 처리할 어딘가에 캡처해야 한다는 것을 깨달았습니다 .
해결책
나는 Bash에서 일반적으로 처리 및 전파가 어떻게 수행되는지 모르기 때문에 SIGINT
지식에 근거한 추측을 했고 효과가 있을 것이라고 생각했지만 확실하지 않은 솔루션을 생각해냈습니다.
#!/bin/bash
function example()
{
(
echo "Main script started"
# Make process run forever in the background.
(
trap "echo Cleanup; trap - SIGINT; kill -s SIGINT ${$}" SIGINT
while sleep 1; do echo "Background script running"; done
) &
# Make subshell work for 10 seconds.
local output="$(sleep 10; echo "Subshell completed")"
echo "${output}"
# Kill the backgrounded process once the subshell has finished.
{ kill "${!}" && wait "${!}"; } &> /dev/null
echo "Main script completed"
)
}
질문
- 내 트랩이 올바르게 처리/전파됩니까
SIGINT
? - 이것이
${$}
올바른 과정인가요?
(언급된 게시물에서는 프로세스가 스스로 종료되어야 한다고 말하지만 예제에서는${$}
이를 대신 사용합니다${BASHPID}
.)