web-dev-qa-db-ja.com

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

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

知っているfork()execve()loaderdynamic linker(およびその他のもの)が関係しますが、誰かが正確な一連のステップと適切な読み取りリファレンスを提供できますか?

編集:

答えから、質問は多くの可能性を暗示することができるようです。単純なケースに絞り込みたい:

(test.cはhello worldを出力するだけです)

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

上記の場合の手順は何ですか(./test)、特にいくつかの子プロセスでのbash起動プログラムの関連付け、ロード、リンクなどの実行?

11
Jake

まあ、実際のプログラムが実行される前に最初に展開/解釈されるシェルのエイリアスまたは関数があり、次に修飾されたファイル名(_/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シェルへ」)は、シェルの側面をより詳細にカバーします。

5
thrig

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

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

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

1
hildred

セクションを読むことをお勧めします8.4.6 forkとexecveを使用してプログラムを実行する

on http://www.groupes.polymtl.ca/inf2610/documentation/ComputerSystemBook.pdf

0
xiaokaoy