백그라운드에서 실행될 때 왜 (...) 새 하위 프로세스를 생성하지 않습니까?

백그라운드에서 실행될 때 왜 (...) 새 하위 프로세스를 생성하지 않습니까?

명령을 실행한 후

{ sleep 5; } &  

출력은 ps(출력 1)

 PID TTY           TIME CMD
  972 ttys000    0:00.27 -bash
 2556 ttys000    0:00.00 -bash
 2557 ttys000    0:00.00 sleep 5   

동시에

( sleep 5 ) &    

출력 ps은 (출력 2)

PID TTY           TIME CMD
 972 ttys000    0:00.28 -bash
2566 ttys000    0:00.00 sleep 5  

(){ sleep 5; } &결과적으로 하위 쉘 환경이 발생하는 경우 이 경우 분기된 하위 프로세스가 발생하기 때문에 "출력 1"이 예상되는 반면, 현재 쉘에서 실행되므로 "출력 2"가 예상됩니다 . 어리석은 질문처럼 보일 수도 있지만, 저는 이러한 행동을 정말 이해하지 못합니다.
내가 여기서 무엇을 놓치고 있는 걸까요?

답변1

Bash는 서브셸의 마지막 또는 유일한 명령을 실행합니다.그리고exec최적화로서 안전하게 그렇게 할 수 있다고 생각한다면. 다음을 통해 이를 명확하게 확인할 수 있습니다 pstree.

$ pstree $$
bash---pstree
$ ( pstree $$ )
bash---pstree
$ ( pstree $$ ; echo)
bash---bash---pstree

$ 

이것이 바로 명령이 중간 쉘 없이 명령 ( sleep 5 )으로만 나타나는 이유입니다. sleep위의 마지막 예에서 echo쉘은 pstree완료된 후 강제로 작업을 수행하므로 중간 경우에 실제 쉘을 사용할 수 있으며 결과 쉘은 즉시 execs pstree이므로 첫 번째 경우와 동일하게 보입니다(표준입니다.분기 실행). 많은 쉘이 이를 수행합니다.


반면에,아무것백그라운드에서 실행하려면 새 프로세스를 생성해야 합니다.: 기본적으로 이것은 "배경"입니다. 중괄호 안의 명령하다일반적으로 현재 셸에서 실행되지만 백그라운드에서 실행되는 경우에는 이런 일이 발생하지 않습니다. 백그라운드 명령이 실행되는 동안 상위 셸이 수행 중인 작업을 계속하려면 전체 셸을 실행하는 새 셸을 만들어야 합니다 { ... }.

$ { pstree $$ ; }
bash---pstree
$ { pstree $$ ; } &
bash---bash---pstree

이 경우 다른 후행 명령이 있는지 여부는 아무런 차이가 없습니다.Bash는 이 동작을 문서화합니다.&:

명령이 제어 연산자 " &"에 의해 종료되면 쉘은 서브쉘에서 명령을 비동기적으로 실행합니다. 이를 백그라운드에서 명령을 실행한다고 합니다. 쉘은 명령이 완료될 때까지 기다리지 않고 상태 0(true)을 반환합니다.

다음을 통해 백그라운드에서 이런 일이 일어나는 것을 볼 수도 있습니다.다음과 같은 내장 명령read:

$ read &
$ pstree $$
[1] 32394
[1]+  Stopped                 read
$ pstree $$
bash-+-bash
     `-pstree

내 껍질은 이제하위: bash실행 중이며 readpstree출력을 인쇄하는 명령입니다.


셸이 추가 최적화를 수행하고 마치 괄호로 묶인 하위 셸에 적용된 것처럼 뒤에서 적용할 수 있다는 것은 사실 { ... }이지만 그렇지 않습니다. 일부 다른 쉘에서는 이 작업을 수행할 수 있지만 빠른 테스트에서는 찾지 못했습니다. 이는 매우 드문 경우이며 형태가 다르며 일부 이상한 경우도 있습니다.

관련 정보