다음과 같은 간단한 bash 스크립트가 있다고 가정해 보겠습니다.
test_bg.sh
#!/bin/bash
ping www.google.ro &> /dev/null &
./test_bg.sh
실행 하고 ps -ef
후속 조치를 통해 직접 실행하면 프로세스 ping www.google.ro
가 systemd(PID 1)에 의해 상속되는 것을 볼 수 있습니다. 즉, 상위 프로세스가 완료될 때까지 기다리지 않고 종료되어 고아 프로세스를 얻게 됩니다.
UID PID PPID PGID SID C STIME TTY TIME CMD
root 1 0 1 1 0 Jan07 ? 00:00:21 /usr/lib/systemd/systemd --system --deserialize 21
...
...
...
nimus 461772 1 461771 458695 0 18:59 pts/1 00:00:00 ping www.google.ro
/bin/bash -c "ping www.google.ro &> /dev/null &"
물론 .
없이 스크립트의 코드를 실행하면 &
스크립트의 코드는 다음과 같습니다 test_fg.sh
.
#!/bin/bash
ping www.google.ro &> /dev/null
다음과 같습니다 ps -efj --forest
.
UID PID PPID PGID SID C STIME TTY TIME CMD
nimus 458695 458596 458695 458695 0 17:02 pts/1 00:00:00 | \_ -bash
nimus 461907 458695 461907 458695 0 19:02 pts/1 00:00:00 | \_ /bin/bash ./test_fg.sh
nimus 461908 461907 461907 458695 0 19:02 pts/1 00:00:00 | \_ ping www.google.ro
/bin/bash ./test_fg.sh
따라서 분기된 프로세스는 다시 fork() 및 exec() 이후에도 ping www.google.ro
여전히 존재합니다 .
물론, ping www.google.ro &> /dev/null &
메인 bash 프로세스(즉, 세션 리더)에서 직접 실행하면 다음과 같은 결과를 얻을 수 있습니다.
[nimus@localhost ~]$ ping www.google.ro &> /dev/null &
[1] 462091
[nimus@localhost ~]$ ps -efj --forest
UID PID PPID PGID SID C STIME TTY TIME CMD
root 458581 351997 458581 458581 0 17:02 ? 00:00:00 \_ sshd: nimus [priv]
nimus 458596 458581 458581 458581 0 17:02 ? 00:00:00 | \_ sshd: nimus@pts/1
nimus 458695 458596 458695 458695 0 17:02 pts/1 00:00:00 | \_ -bash
nimus 462091 458695 462091 458695 0 19:10 pts/1 00:00:00 | \_ ping www.google.ro
그렇다면 프로세스가 ping www.google.ro
스크립트의 백그라운드에서 실행될 때 프로세스가 상속되는 이유는 무엇입니까?Systemd PID 1
&
답변1
백그라운드에서 프로세스를 시작하면( 를 사용하여 &
) 상위 프로세스와 동시에 실행이 시작됩니다. 스크립트에는 다른 작업이 없으므로 exit
고아 프로세스가 사용됩니다 init
. 이를 사용하지 않으면 &
부모는 wait
자식이 완료될 때까지 기다렸다가 일시 중지됩니다. 스크립트를 상위 스크립트로 처리합니다. 후자의 경우 부모는 정지/수면 상태로 나타납니다.
답변2
스크립트를 실행하는 프로세스가 종료됩니다.마지막에 도달하기 때문에스크립팅됨. 명령이 백그라운드에서 실행되기 때문에 스크립트의 끝에 도달합니다 &
.