exec bash 내장은 내부적으로 어떻게 작동합니까?

exec bash 내장은 내부적으로 어떻게 작동합니까?

에서이것link exec bash 내장 명령에 대해 다음을 얻습니다.

명령이 제공되면쉘을 대체합니다새로운 프로세스를 만들지 않고.

쉘을 정확히 어떻게 대체합니까(즉, 내부적으로 어떻게 작동합니까)? exec*()시스템 호출이 동일하게 작동 합니까 ?

답변1

예, 내장 기능은 궁극적으로 시스템 호출 계열 exec중 하나를 사용합니다 . exec*()정상적으로 명령을 실행하는 경우도 마찬가지입니다. 단지 를 사용할 때 새 프로세스를 생성하기 위해 먼저 시스템 호출을 exec사용하지 않고 fork()결과적으로 새 명령이 셸을 대체한다는 것입니다.

답변2

strace실행 중인 인스턴스에서 작업을 수행했습니다 bash. 그런 다음 명령을 호출했습니다 exec sleep 100. 이제 무슨 일이 일어났는지 보세요:

access("/bin/sleep", X_OK)              = 0
...
execve("/bin/sleep", ["sleep", "100"], [/* 14 vars */]) = 0
...
nanosleep({100, 0},
...
exit_group(0)                           = ?

보시다시피 sleep일반적인 방법으로 호출할 때와 거의 동일하게 발생했습니다. 시스템 호출을 통해 bash실행 권한( X_OK)이 부여되었는지 확인합니다 . 그런 다음 파일 이름이 가리키는 프로그램을 실행합니다. syscall 이후 프로세스를 제어할 수 있습니다. 그것은 무엇인가: . 또한 동일한 PID를 유지합니다. 종료 되면 프로세스도 종료됩니다. 더 이상 실행되지 않는지 여부입니다 ./bin/sleepaccess()execve()execve()sleepnanosleep()sleepsleepbash

증거:

다른 창에서 나는 ps. 명령을 실행하기 전의 모습은 다음과 같았습니다.

$ ps -o stat,pid,cmd -p <pid>
Ss+  10905 -bash

그리고 실행하는 동안:

$ ps -o stat,pid,cmd -p <pid>
Ss+  10905 sleep 100

Afer는 sleep프로세스를 종료하고 사라졌습니다.

정상적으로 실행하면 어떻게 되나요?

access("/bin/sleep", X_OK)              = 0
...
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6c9fd089d0) = 19261
...
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 19261
...
--- SIGCHLD (Child exited) @ 0 (0) ---

실행 권한이 확인됩니다. 그런 다음 하위 프로세스가 생성됩니다 clone(). 인스턴스 bash는 이제 백그라운드 프로세스 그룹, sleep포그라운드 프로세스 그룹에 있습니다. 그리고 마지막으로 wait4()호출은 하위 프로세스가 종료될 때까지 기다립니다(100초 필요).

관련 정보