シェルからファイルを実行すると、正確に何が起こりますか?

シェルからファイルを実行すると、正確に何が起こりますか?

だから私はこれについてかなりよく理解したと思いましたが、私はテストを試してみました(私が同意しない誰かの会話に答えて)私の理解に欠陥があることに気づきました...

できるだけ詳しく説明してください。シェルからファイルを実行すると、正確に何が起こりますか?つまり、./somefile some argumentsシェルに次のように入力してEnterキーを押すと(somefilecwdに存在し、読み取り+実行権限がありますsomefile)、後で何が起こりますか?

アイデア正解は:

  1. シェルはシステムにシステムコールを実行してexecパスを渡します。somefile
  2. カーネルの確認somefileと参照マジックナンバープロセッサが処理できる形式であることを確認するためのファイルです。
  3. マジック番号がファイルがプロセッサが実行できる形式であることを示す場合
    1. 新しいプロセスの作成(プロセステーブルにエントリがあります)
    2. somefileメモリに読み込まれるかマップされます。スタックを作成し、コードのエントリポイントにジャンプを実行してから、パラメータsomefile配列ARGV(a char**["some","arguments"])で初期化します。
  4. マジックナンバーならシェルボーン次に、上記のように新しいプロセスを作成しますが、shebang(または)で参照し、次に渡されるインタプリタである実行可能exec()ファイルを使用します。/bin/bash/bin/perlsomefileSTDIN
  5. ファイルに有効なマジック番号がない場合は、「無効なファイル(無効なマジック番号):Exec形式のエラー」などのエラーが発生します。

しかし、ファイルがプレーンテキストの場合、シェルは(私が入力したように)コマンドを実行しようとすると聞きましたbash somefile。もともとは信じていなかったけど、いざやってみたらそれが合ったんですよ。だから、ここで実際に何が起こっているのかについては明らかに少し誤解があり、メカニズムを理解したいと思います。

シェルからファイルを実行すると、正確に何が起こりますか? (できるだけ詳しく...)

ベストアンサー1

「Linuxでプログラムを実行する方法」に対する明確な答えは、次の2つの記事です。greennet.comタイトルは驚くべきことに、プログラムの仕組みそしてプログラムの実行方法:ELFバイナリ。最初の記事では、スクリプトを簡単に紹介します。 (技術的には最終的な答えはソースコードにありますが、これらの記事は読みやすく、ソースコードへのリンクを提供します。)

一部の実験では、ほぼ正しく実行され、単純なコマンドのリスト(shebangなし)を含むファイルの実行はシェルで処理する必要があることを示しています。これ実行(2)マンページには、テストプログラムexecveのソースコードが含まれています。これを使用して、シェルなしで何が起こるかを見てみましょう。まず、以下をtestscr1含むテストスクリプトを作成します。

#!/bin/sh

pstree

そして別のものにはtestscr2以下が含まれます。

pstree

両方を実行可能にし、両方がシェルで実行されていることを確認します。

chmod u+x testscr[12]
./testscr1 | less
./testscr2 | less

それでは、次を使用してもう一度やり直してくださいexecve(現在のディレクトリにビルドしているとします)。

./execve ./testscr1
./execve ./testscr2

testscr1それでも実行されますが、testscr2生成されます。

execve: Exec format error

これは、シェルが物事をtestscr2異なる方法で処理することを示します。スクリプト自体を処理するわけではありませんが、/bin/shそれを実行するために使用されます。これはパイピングでtestscr2確認できますless

./testscr2 | less -ppstree

私のシステムでは、私は得る。

    |-gnome-terminal--+-4*[zsh]
    |                 |-zsh-+-less
    |                 |     `-sh---pstree

ご覧のとおり、私が使用したシェルがzsh始まり、2番目のシェルは(私のシステムで)スクリプトを実行するless一般的なシェルでした。これはinで処理されます。shdashpstreezshzexecveSrc/exec.c:shellはコマンドの実行に使用されますexecve(2)。失敗した場合は、ファイルを読み取ってshebangがあるかどうかを確認し、それに応じて処理します(カーネルもこれを行います)。失敗すると、ファイルが存在している間にshファイルを実行しようとします。ファイルにシャバンがありません。以下から0バイトを読んでください。

        for (t0 = 0; t0 != ct; t0++)
            if (!execvebuf[t0])
                break;
        if (t0 == ct) {
            argv[-1] = "sh";
            winch_unblock();
            execve("/bin/sh", argv - 1, newenvp);
        }

bash同じ動作が実装されています。execute_cmd.c役に立つコメント(示されているように)タレジン):

一部のディスクファイルで定義されている単純なコマンドを実行します。

  1. fork ()
  2. パイプ接続
  3. 検索コマンド
  4. リダイレクトする
  5. execve ()
  6. 失敗した場合は、execveファイルに実行モードが設定されていることを確認してください。その場合はディレクトリではなく、その内容はシェルスクリプトとして実行されます。

POSIX は、次の関数セットを定義します。exec(3)機能execve(2)この機能をラップして提供します。ムル詳しくはお答えください。 Linuxでは、少なくともこれらの機能はカーネルではなくCライブラリによって実装されています。

おすすめ記事