GNU/Linux >> Linux の 問題 >  >> Linux

シェルでファイルを実行するとどうなりますか?

それで、私はこれをよく理解していると思いましたが、(誰かと意見が合わなかった会話に応えて)テストを実行したところ、私の理解に欠陥があることがわかりました…

可能な限り詳細に シェルでファイルを実行するとどうなりますか?つまり、次のように入力すると、 ./ somefile some arguments シェルに入れてreturnキーを押します(そして somefile cwdに存在し、 somefileに対する読み取り+実行権限があります )それでは、内部で何が起こりますか?

私は考えた 答えは:

  1. シェルはexecへのシステムコールを行います 、パスを somefileに渡します
  2. カーネルはsomefileを調べます ファイルのマジックナンバーを調べて、それがプロセッサが処理できる形式であるかどうかを判断します
  3. マジックナンバーが、ファイルがプロセッサが実行できる形式であることを示している場合は、
    1. 新しいプロセスが作成されます(プロセステーブルのエントリを使用)
    2. somefile 読み取り/メモリにマッピングされます。スタックが作成され、実行が somefileのコードのエントリポイントにジャンプします。 、 ARGVを使用 パラメータの配列に初期化されます( char ** ["some"、 "arguments"]
  4. マジックナンバーがシバンの場合、 exec() 上記のように新しいプロセスを生成しますが、使用される実行可能ファイルは、シバンによって参照されるインタープリターです(例: / bin / bash または/bin / perl )および somefile STDINに渡されます
  5. ファイルに有効なマジックナンバーがない場合、「無効なファイル(不正なマジックナンバー):Execフォーマットエラー」などのエラーが発生します

ただし、ファイルがプレーンテキストの場合、シェルはコマンドを実行しようとする( bash somefile と入力したかのように)と誰かが教えてくれました。 )。信じられませんでしたが、試してみたところ、正しかったです。ですから、私は明らかにここで実際に何が起こっているのかについていくつかの誤解を持っており、メカニズムを理解したいと思います。

シェルでファイルを実行するとどうなりますか? (詳細は合理的です…)

承認された回答:

Linuxでの「プログラムの実行方法」に対する決定的な答えは、LWN.netの「プログラムの実行方法」と「プログラムの実行方法:ELFバイナリ」というタイトルの2つの記事です。最初の記事では、スクリプトについて簡単に説明します。 (厳密に言えば、決定的な答えはソースコードにありますが、これらの記事は読みやすく、ソースコードへのリンクを提供します。)

少し実験してみると、ほぼ正しく理解できており、コマンドの単純なリストを含むファイルの実行は、シバンなしでシェルで処理する必要があります。 execve(2)のマンページには、テストプログラムexecveのソースコードが含まれています。これを使用して、シェルなしで何が起こるかを確認します。まず、テストスクリプト testscr1を記述します。 、含む

#!/bin/sh

pstree

もう1つは、 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 lessを開始しました 、および2番目のシェル、プレーン sh ダッシュ 私のシステムでは)、 pstreeを実行したスクリプトを実行します 。 zshで これはzexecveによって処理されます Src / exec.c内 :シェルは execve(2)を使用します コマンドの実行を試み、それが失敗した場合は、ファイルを読み取ってシバンがあるかどうかを確認し、それに応じて処理し(カーネルも実行します)、失敗した場合は、 sh 、ファイルからゼロバイトを読み取らなかった場合:

        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で実装された同じ動作をします 役立つコメント付き(taliezinが指摘):

うまくいけばどこかのディスクファイルで定義されている簡単なコマンドを実行します。

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

POSIXは、 exec(3)と呼ばれる一連の関数を定義します。 execve(2)をラップする関数 この機能も提供します。詳細については、muruの回答を参照してください。 Linuxでは、少なくともこれらの関数はカーネルではなくCライブラリによって実装されます。

関連:Bash forループの「do」キーワードの目的は?
Linux
  1. コマンドCat/proc / cpuinfoを実行するとどうなりますか?

  2. Linux –宛先パスなしでRsyncするとどうなりますか?

  3. Linuxでの.bashrcファイルの目的は何ですか

  1. 指定したファイルが移動または削除された場合、Linux で開いているファイル ハンドルはどうなりますか

  2. Linuxでシェルスクリプトを実行しようとすると、バイナリファイルを実行できません

  3. スレッドが分岐するとどうなりますか?

  1. シェルで .sh 拡張子のないファイルを実行する方法

  2. 実行権限は何をしますか?

  3. Busybox のデフォルト シェルとは何ですか?