백그라운드에서 시작되는 명령이 포함된 bash 스크립트를 사용하고 있습니다 script.sh
.cmd
#!/bin/bash
…
cmd &
…
터미널 에뮬레이터를 열고 실행하면 script.sh
예상 cmd
대로 백그라운드에서 올바르게 실행됩니다. 즉, script.sh
종료되었음에도 불구하고 cmd
PPID 1로 백그라운드에서 계속 실행됩니다.
그러나 이전 터미널 에뮬레이터(또는 실제 사용 사례인 데스크톱 세션 시작 부분)에서 다른 터미널 에뮬레이터(xfce4-terminal이라고 가정)를 열고 다음 script.sh
을 실행하면
xfce4-terminal -H -x script.sh
cmd
더 이상 올바르게 실행되지 않습니다. 종료됩니다 script.sh
. 단순히 nohup
예방하는 것만으로는 충분하지 않습니다. 나는 sleep
그 뒤에 명령을 내려야 할 의무가 있습니다. 그렇지 않으면 cmd
에서 연결이 해제되기 전에 의 종료로 인해 종료됩니다.script.sh
cmd
백그라운드에서 올바르게 수행하는 유일한 방법은 첫 번째 경우가 아닌 이 경우에 필요한 이유는 무엇입니까 set -m
? script.sh
두 실행 script.sh
(따라서 cmd
) 사이에 동작에 차이가 있는 이유는 무엇입니까?
첫 번째 경우에는 시계 모드가 다음과 같다고 가정합니다.아니요set -o
를 입력하면 볼 수 있듯이 활성화됩니다 script.sh
.
답변1
실행해야 하는 프로세스는 사이의 신호에 의해 종료되며 cmd
래퍼 또는 기타 항목은 실행될 기회가 없으며 아무런 효과도 없습니다. (체크를 사용해도 됩니다)SIGHUP
fork()
exec()
nohup
strace
nohup
백그라운드 명령을 실행하기 전에 상위 셸에서 SIGHUP
(ignore)로 설정해야 합니다. SIG_IGN
신호 처리기가 "ignore" 또는 "default"로 설정된 경우 구성이 전달되고 fork()
상속 됩니다 exec()
. 예:
#! /bin/sh
trap '' HUP # ignore SIGHUP
xclock &
trap - HUP # back to default
또는:
#! /bin/sh
(trap '' HUP; xclock &)
xfce4-terminal -H -x script.sh
다음을 사용하여 이 스크립트를 실행 xclock &
하면SIGHUP
script.sh
세션 리더(귀하의 경우 제어 터미널을 "소유"하는 프로세스 script.sh
)가 종료되면 커널이 SIGHUP
해당 리더 에서 실행됩니다.전망프로세스 그룹이지만 작업 제어가 활성화 되고 set -m
다음으로 시작하는 명령이 활성화 됩니다.&
배경프로세스 그룹을 통해 신호를 내보내지 않습니다 SIGHUP
.
작업 제어가 활성화되지 않은 경우(비대화형 스크립트의 기본값 &
)전망프로세스 그룹, "백그라운드" 모드는 위조됩니다.리디렉션그들의 의견을 /dev/null
받아들이고소홀히 하다 SIGINT
그리고 SIGQUIT
.
SIGHUP
프로세스는 한때 포그라운드 작업으로 실행되었지만 해당 프로세스 그룹(죽은 상위 프로세스에서 상속됨)이 더 이상 터미널의 포그라운드 프로세스가 아니기 때문에 종료된 스크립트에서 이러한 방식으로 신호를 받습니다 .
추가 지침:
xterm
와 (그리고 아마도 다른 vte 기반 터미널) xfce4-terminal
사이에 "보류 모드"에 차이가 있는 것 같습니다 . 전자는 pty의 마스터 측을 열어 두는 반면, 후자는 프로그램이 실행되거나 종료된 후 pty를 찢어서 -e
슬레이브 -x
측에 대한 모든 쓰기가 실패하고 표시되게 합니다 EIO
. 포그라운드 프로세스 그룹에서 프로세스가 계속 실행 중인 동안에는 xterm
메시지도 무시됩니다(즉, 닫히지 않습니다) .WM_DELETE_WINDOW
답변2
나는 이것을 가지고 놀았습니다. 나는 그것을 알아낼 수 없었지만 여기에 내가 찾은 것이 있습니다. 나는 명령으로 sleep 3을 사용합니다.
이 두 가지가 작동합니다. ls
최종 효과가 무엇인지 모르겠습니다 . 대괄호와 double 은 nohup
하위 프로세스를 형성합니다(그게 작동하는 방식이라고 생각합니다 nohup
). 왜 nohup
자체적으로 작동하지 않는지 모르겠습니다 .
#!/bin/bash
nohup nohup sleep 3 &
ls #no idea why I need this
그리고
#!/bin/bash
(
nohup sleep 3 &
ls #no idea why I need this
)
/bin/true
교체작업 ls
. 외부 명령을 호출해야 할 것 같습니다. 아직도 이유를 모르겠습니다.