シェルはどのようにプログラムを実行しますか?


11

gccを使用してプログラムをコンパイルし、それをbashシェルから実行しようとすると、それを実行するためにbashが実行するステップの正確なシーケンスは何ですか?

私が知っているfork()execve()loaderdynamic 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 2015

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)。また、プロセスグループも重要です(特に、フォアグラウンドプロセスグループ。SIGINTCtrl+ C、セッション、およびジョブがバックグラウンドで実行されるか、監視されるか(foo &)またはバックグラウンドで無視されるか()でマッシュアップが開始されたときfoo & disown。I / Oリダイレクションの詳細は、たとえば、標準入力がシェルによって閉じられた場合(foo <&-)、またはファイルがstdinとして開かれた場合()なども変更しますfoo < blah

straceまたは同様のものは、このプロセスに沿って行われた特定のシステムコールについての情報を提供し、それらの各コールのマニュアルページが存在する必要があります。シェルブック(たとえば、「BashからZシェルへ」)は、物事のシェル側をより詳しくカバーする一方で、適切なシステムレベルの読みは、Stevensの「UNIX環境での高度なプログラミング」の任意の数の章になります。


私は質問を編集して単純なケースに絞り込みました
Jake

1

(動的リンカーが実行されるように)すでに実行されている(コードを明確にするための)教科書の例のシェルを想定すると、言及するコマンドは、次のシステムコールを実行するシェルを必要とします。

  • 読み取り:この場合は次のコマンドを取得しますgcc
  • fork:2つのプロセスが必要です。親はpid 500で、説明のために子があると仮定します。
  • 親はwait(501)を呼び出し、子はexecを呼び出します。この時点で、シェルはpid 501で実行されていません。gccは、最低限のオープン、クローズ、読み取り、書き込み、chmod、fork、exec、待機、終了など、多くのシステムコールを実行します。
  • gccがexitを呼び出すと、waitが戻り、writeが呼び出されてプロンプトが表示され、プロセスが繰り返されます。

もちろん、より複雑なコマンドを使用すると、この基本的なシーケンスがさらに複雑になります。基本的な複雑さの2つのより単純な例は、オープン、クローズ、dupシーケンスがforkとexecの間に挿入される基本的なioリダイレクションと、待機がスキップされる(そして別の待機がsigchldハンドラーに追加される)バックグラウンドプロセスです。


小さな追加:ロードと動的リンクについて質問します。静的にリンクされているすべてのコード、つまり実際にプログラムファイルに含まれているコードは、プログラムが起動する前にカーネルによって実行されます。動的に読み込まれるライブラリ、つまり個別のファイルは、main()を開始する前にプログラム自体によって処理されます。このためのコードはgccによって自動的に追加されます。
Stig Hemmer、2015

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.