명령을 실행한 후
{ 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
완료된 후 강제로 작업을 수행하므로 중간 경우에 실제 쉘을 사용할 수 있으며 결과 쉘은 즉시 exec
s pstree
이므로 첫 번째 경우와 동일하게 보입니다(표준입니다.분기 실행). 많은 쉘이 이를 수행합니다.
반면에,아무것백그라운드에서 실행하려면 새 프로세스를 생성해야 합니다.: 기본적으로 이것은 "배경"입니다. 중괄호 안의 명령하다일반적으로 현재 셸에서 실행되지만 백그라운드에서 실행되는 경우에는 이런 일이 발생하지 않습니다. 백그라운드 명령이 실행되는 동안 상위 셸이 수행 중인 작업을 계속하려면 전체 셸을 실행하는 새 셸을 만들어야 합니다 { ... }
.
$ { pstree $$ ; }
bash---pstree
$ { pstree $$ ; } &
bash---bash---pstree
이 경우 다른 후행 명령이 있는지 여부는 아무런 차이가 없습니다.Bash는 이 동작을 문서화합니다.&
:
명령이 제어 연산자 "
&
"에 의해 종료되면 쉘은 서브쉘에서 명령을 비동기적으로 실행합니다. 이를 백그라운드에서 명령을 실행한다고 합니다. 쉘은 명령이 완료될 때까지 기다리지 않고 상태 0(true)을 반환합니다.
다음을 통해 백그라운드에서 이런 일이 일어나는 것을 볼 수도 있습니다.다음과 같은 내장 명령read
:
$ read &
$ pstree $$
[1] 32394
[1]+ Stopped read
$ pstree $$
bash-+-bash
`-pstree
내 껍질은 이제둘하위: bash
실행 중이며 read
이 pstree
출력을 인쇄하는 명령입니다.
셸이 추가 최적화를 수행하고 마치 괄호로 묶인 하위 셸에 적용된 것처럼 뒤에서 적용할 수 있다는 것은 사실 { ... }
이지만 그렇지 않습니다. 일부 다른 쉘에서는 이 작업을 수행할 수 있지만 빠른 테스트에서는 찾지 못했습니다. 이는 매우 드문 경우이며 형태가 다르며 일부 이상한 경우도 있습니다.