쉘은 어떻게 프로그램을 실행합니까?


11

gcc를 사용하여 프로그램을 컴파일하고 bash 쉘에서 실행하려고하면 정확한 단계 순서와 bash가 실행됩니다.

내가 알고 fork(), execve(), loader, dynamic linker(그리고 다른 것들) 관여하지만, 캔 누군가가 단계의 정확한 순서와 일부 적합한 독서 참조를 제공?

편집하다:

대답에서, 그 질문은 많은 가능성을 암시 할 수있는 것 같습니다. 간단한 경우로 좁히고 싶습니다.

(test.c는 hello world를 인쇄합니다)

$ gcc test.c -o test
$ ./test

위의 경우 ( ./test) 의 단계 , 특히 일부 하위 프로세스의 bash 시작 프로그램과 관련하여로드, 링크 등을 수행하는 단계는 무엇입니까?


4
난 당신이 읽을 초대 lwn.net/Articles/630727
cuonglm

3
왜 strace bash -c 'test'를 시도하지 않습니까?
Sergiy Kolodyazhnyy

2
괜찮은 운영 체제 교과서가 OP의 좋은 리소스가 될 것 같습니다. 이와 같은 개별적인 질문을 통해 운영 체제의 작동 방식을 배우려고하는 것은 생산적인 프로세스가 아닐 수 있습니다.
Barmar

쉘의 최소한의 예를 보는 것이 유용합니다 : brennan.io/2015/01/16/write-a-shell-in-c
jinawee

답변:


5

실제 프로그램이 실행되기 전에 먼저 확장 / 해석되는 셸 별명이나 함수가있을 수 있고, 정규화 된 파일 이름 ( /usr/libexec/foo)과 모든 디렉토리에서 찾을 수있는 것의 차이점이 있기 때문에 정확한 순서는 다를 수 있습니다. 의 PATH환경 변수 (단지 foo). 또한, 실행의 세부 사항으로, 문제를 복잡하게 할 수있다 foo | bar | zot(몇 개의 쉘에 대한 더 많은 작업이 필요합니다 fork(2), dup(2)물론,와 pipe(2)같은 것이 있지만, 다른 시스템 호출 사이에서) exec foo훨씬 적은 작업이 쉘은 단지 자신을 대체로 새로운 프로그램 (즉, 그렇지 않습니다 fork). 또한 프로세스 그룹 (특히 포 그라운드 프로세스 그룹, 모든 PID가 먹는 그룹)도 중요합니다.SIGINT누군가가 Ctrl+ C에서 세션을 시작 하고 세션 및 작업이 백그라운드에서 실행 될지 모니터링되는지 ( foo &) 또는 백그라운드에서 무시 되는지 ( foo & disown) I / O 리디렉션 세부 사항은 예를 들어 표준 입력이 쉘 ( foo <&-)에 의해 닫히 거나 파일이 stdin ( foo < blah)으로 열리는 지 등을 변경합니다 .

strace이 과정에서 수행 된 특정 시스템 호출에 대한 정보는 이와 비슷하며 각 호출에 대한 매뉴얼 페이지가 있어야합니다. 적절한 시스템 레벨 읽기는 Stevens의 "UNIX 환경에서의 고급 프로그래밍"의 여러 장이 될 것이며 쉘 책 (예 : "Bash에서 Z Shell로")은 쉘의 측면을 더 자세히 다룰 것입니다.


간단한 사례로 좁히기 위해 질문을 수정했습니다.
Jake

1

이미 실행중인 (코드 명확성을 위해) 교과서 예제 쉘 (동적 링커가 수행됨)을 가정 할 때 언급 한 명령을 수행하려면 쉘에서 다음 시스템 호출을 수행해야합니다.

  • 읽기 :이 경우 다음 명령을 얻습니다 gcc
  • 포크 : 두 가지 과정이 필요합니다. 우리는 부모가 pid 500을 가지고 있고 그림을 위해 아이를 가지고 있다고 가정합니다.
  • 부모는 wait (501)를 호출하고 자식은 exec를 호출합니다. 이 시점에서 쉘은 더 이상 pid 501에서 실행되지 않습니다. gcc는 최소한 open, close, read, write, chmod, fork, exec, wait 및 exit를 포함하여 많은 시스템 호출을 수행합니다.
  • gcc 호출이 종료되면 대기가 반환되고 프롬프트가 표시되도록 쓰기가 호출되고 프로세스가 반복됩니다.

물론 더 복잡한 명령은이 기본 시퀀스에 더 복잡한 문제를 추가합니다. 기본 합병증의 간단한 두 가지 예는 포크와 exec 사이에 열린 dup 시퀀스가 ​​삽입되고 대기가 생략 된 백그라운드 프로세스와 또 다른 대기가 sigchld 핸들러에 추가되는 기본 io 리디렉션입니다.


작은 추가 사항 :로드 및 동적 링크에 대한 질문입니다. 정적으로 링크 된, 즉 실제로 프로그램 파일에 포함 된 모든 코드는 프로그램이 시작되기 전에 커널에 의해 수행됩니다. 동적으로로드 된 라이브러리, 즉 별도의 파일은 main ()을 시작하기 전에 프로그램 자체에서 처리합니다. 이에 대한 코드는 gcc에 의해 자동으로 추가됩니다.
Stig Hemmer

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.