Linux 시스템에서는 bash 내장 명령을 disown
사용하여 현재 세션에서 작업을 삭제할 수 있습니다. Bash는 이 기능을 어떻게 구현합니까? 여기서 사용됩니다 setsid()
. 사용되는 경우 bash는 하위 프로세스 호출을 어떻게 트리거합니까 setsid()
? 신호를 사용하나요?
답변1
disown
아니요아니요현재 세션[1]에서 작업을 제거해도 작업이 터미널에서 분리되지 않으며 세션 리더가 종료되거나 제어 터미널이 철거될 때 커널이 보내는 신호에 영향을 주지 않습니다.
disown
SIGHUP
bash 자체 작업 목록에만 적용되고, bash가 제어하는 작업에 대한 bash의 생각만 변경하며, bash 자체 동작에만 영향을 미칩니다. 즉, bash 프로세스에서 받은 작업을 다시 보냅니다 . 재전송은 표준에서 요구하지 않는 SIGHUP
[2]의 추가 기능이며 운영 체제에서 제공하는 작업 제어와 무관합니다.bash
script(1)
pty를 생성하고 그 안에서 대화형 셸 세션을 실행하는 간단한 예를 통해 이를 확인할 수 있습니다 .
$ script /dev/null -qc bash
$ sh -c 'sleep 555 & sleep .1; kill -STOP $!; trap "echo hupped!" HUP; sleep 666' &
[1] 3837
$ disown -a
$ jobs
# no jobs known to bash
$ pgrep -as0
# show all processes from the current session
3836 bash
3837 sh -c sleep 555 & sleep .1; kill -STOP $!; trap "echo hupped!" HUP; sleep 666
3838 sleep 555
3841 sleep 666
$ kill -HUP $$
# seppuku the session leader
Hangup
hupped!
여기서 커널은 SIGHUP
프로세스 중 하나가 중지되어 포기하게 되므로 백그라운드 프로세스 그룹(=job)에 신호를 보냅니다.아니요이런 일이 발생하지 않도록 하세요.
기본적으로 sh -c '...'
"백그라운드"를 포함하여 의 모든 프로세스는 동일한 작업의 일부이며 쉘 스크립트는 작업 제어를 수행하지 않습니다.sleep &
중지할 백그라운드 프로세스 그룹의 구성원이 없으면 SIGHUP
no를 보냅니다.
$ script /dev/null -qc bash
$ sh -c 'sleep 555 & trap "echo hupped!" HUP; sleep 666' &
[1] 3270
$ disown -a
$ kill -HUP $$
# sleep 555, 666 and sh -c are still running
마지막으로 bash는 SIGHUP
bash가 세션 리더인지, 작업이 실행 중인지, 중지되었는지 등에 관계없이 테이블의 모든 작업(자체적으로 시작되고 거부되지 않은 작업만)에 a를 보냅니다.
$ bash
$ sh -c 'sleep 555 & trap "echo hupped!" HUP; sleep 666' &
[1] 3413
$ kill -HUP $$
Hangup
hupped!
Hangup
[1] 이는 어쨌든 불가능합니다. setsid()
프로세스는 새 세션으로만 생성될 수 있습니다.아니요프로세스 그룹 리더로서 전체 작업을 새 세션이나 기존 세션으로 이동할 수 없습니다.
[2] bash 맨페이지에 문서화되어 있습니다:
SIGHUP
대화형 셸은 종료하기 전에SIGHUP
실행 중이거나 중지된 모든 작업을 다시 보냅니다. 중지된 작업을 보내서SIGCONT
수신되었는지 확인하세요SIGHUP
. 쉘이 특정 작업에 신호를 보내는 것을 방지하려면 내장 명령(아래 쉘 내장 명령 참조)을 사용하여 작업 테이블에서 해당 작업을 제거하거나disown
수신하지 않도록 표시해야 합니다. 를 사용하여 .SIGHUP
disown -h
또 다른 shopt -s huponexit
이유는로그인bash 셸은 종료 시 작업에 를 보냅니다 HUP
(신호로 인한 것인지 여부에 관계 없음). 이는 다시 운영 체제의 표준 작업 제어 기능과 혼란스러운 방식으로 겹칩니다.