Bash가 각 명령을 실행하기 위해 하위 프로세스를 생성하는지 여부

Bash가 각 명령을 실행하기 위해 하위 프로세스를 생성하는지 여부

일반 명령을 여러 번 실행할 때마다 ps프로세스 ID(PID)가 달라집니다. 이것이 우리가 터미널(bash)에서 실행하는 모든 명령이 해당 명령을 실행하기 위해 bash 하위 프로세스를 생성한다는 것을 의미하는지 궁금합니다.

답변1

예, 명령줄에서 실행하는 거의 모든 명령은 자체 프로세스에서 실행되며 해당 프로세스는 이를 시작한 셸의 하위 프로세스입니다.

여기서 예외는 쉘의 내장 명령입니다. Bash는 기본적으로 printf, echo, true및 / 와 같은 일부 표준 유틸리티를 구현하므로 false이러한 유틸리티를 실행해도 kill하위 키를 분기하지 않습니다. , 및 와 같은 항목에도 동일하게 적용됩니다. 단, 셸의 내부 상태에 영향을 주기 때문에 내장되어야 합니다.[testcdreadmapfile

(또한 break, continue, 및 는 이상하게도 및 와 같은 쉘 키워드 return가 아닌 내장 유틸리티입니다 .)ifwhile

쉘이 자신과 동일한 프로세스에서 외부 프로그램을 실행하고 여전히 돌아올 수 있는 방법은 실제로 없습니다. 그러나 쉘에서는 가능합니다.바꾸다다른 프로그램으로 자체적으로. 예를 들어, 쉘의 PID 보기를 실행한 다음 echo $$다음 exec ps을 실행 하면 종료 ps하면 ps쉘이 더 이상 존재하지 않습니다. 실제로 fork()서브루틴( )을 실행하려는 프로그램으로 대체하기 execve()전에 쉘이 자신의 복사본(시스템 호출)을 만드는 점을 제외하면 일반적인 방법으로 프로그램을 실행할 때마다 비슷한 일이 발생합니다. 자식 프로세스에서 실행되는 셸 프로그램 사이에서 자식 프로세스에 대한 리디렉션 등을 설정하는 일을 담당합니다.

쉘은 또한 동일한 프로그램 파일에 있는 더 큰 표준 유틸리티 세트인 Busybox 구현과 같은 다른 도구를 내장으로 구현할 수도 있습니다. 그러나 제가 테스트한 바에 따르면, 하위 프로세스를 실행할 때 여전히 하위 프로세스를 분기합니다. 이는 아마도 유틸리티가 불필요하게 셸 상태를 망칠 수 없는지 확인하는 쉬운 방법이기 때문일 것입니다.

답변2

응, 왜냐하면거의모든 명령[1].

내장 명령으로 구현된 명령 외에도 helpbash[2]에서 이러한 명령 목록을 얻을 수 있습니다.

bash는 내장 명령만 실행하는 경우에도 하위 쉘을 실행할 때 분기됩니다. 예를 들어 (echo a | read p)기본 쉘을 실행하는 프로세스 외에 3개의 별도 프로세스가 있습니다.

[1] 최초의 Unix 쉘(Thompson 쉘)에 대한 원래 아이디어는 다음과 같습니다.모두명령은 별도의 바이너리여야 하며 별도의 프로세스로 실행되어야 합니다. 그러나 디자인 제한과 구현상의 문제로 인해 처음에는 chdir내장으로 구현되고 그다음에는 변수 할당 등을 수행해야 했기 때문에 매우 빠르게 문제가 발생했습니다 . 더 많은 껍질이 원래 아이디어를 점점 침식했습니다.

[2] buitin을 실행할 때에도 bash는 별도의 프로세스를 모방하려고 시도합니다. 예를 들어 from의 리디렉션은 별도의 명령으로 실행되는 환상을 유지하기 위해 echo > filefrom과 완전히 다르게(그리고 매우 복잡하게) 처리 되며 리디렉션은 적용되지 않습니다. 전체 셸, 명령에만 . 예를 들어 Bash는 항상 이렇게 하는 것은 아닙니다.ls > fileechoecho

bash -c 'trap "echo Ctrl-C" INT; read p; echo DONE'

트랩이 INT실행되지 않습니다.뒤쪽에명령 은 read다른 명령과 마찬가지로 반환되었습니다(대시와 같은 다른 쉘이 이를 수행합니다). 또한 차단 내장 기능은 echo어리석은 "인터럽트 시스템 호출"을 반환할 수 있습니다. 이는 /bin/echo외부에서는 절대 수행하지 않는 작업입니다( echo신호 처리기가 필요하지 않거나 설정되지 않기 때문에 ;-)). 그리고 그 흔적을 함께 엮은 수천 개의 유사한 사례가 있습니다. 솔기를 통해.

참고: busybox는 이와 관련이 없습니다. busybox는 와 같은 첫 번째 명령줄 인수를 기반으로 다양한 기능을 수행할 수 있는 프로그램인 다중 호출 바이너리의 예 입니다 ex/vi. od/hexdump그러나 비지박스의 작은 프로그램(셸 ashhush)은 실행할 수 있습니다.일부다른 애플릿은 명시적으로 그런 방식으로 컴파일된 경우 동일한 프로세스 내장 기능으로 작동합니다(NOFORK/NOEXEC애플릿).

답변3

Bash에서 실행하는 대부분의 일반적인 작업은 서로 다른 프로세스이기 때문에 새 PID를 얻습니다(프로세스는 지정된 PID로 시작하고 실행한 다음 완료되고 PID는 새 프로세스에서 사용할 수 있습니다...결국...check zombie processes). 새로운 프로세스(예: echo)를 생성하지 않고 bash에 의해 직접 실행되는 내장 기능이 있습니다.... 그리고 bash 하위 프로세스를 생성하는 것들이 있습니다(각 하위 프로세스에는 자체 PID가 있습니다. 예를 들어 while read이것은 그렇지 않습니다. 잠시 동안 내부에서 수행할 수 있도록 허용합니다 while. 완료되면 새 값이 사라지므로 외부에서 사용할 수 있도록 변수 값을 설정합니다 .

관련 정보