だから私はこれについてかなりよく理解したと思いましたが、私はテストを試してみました(私が同意しない誰かの会話に答えて)私の理解に欠陥があることに気づきました...
できるだけ詳しく説明してください。シェルからファイルを実行すると、正確に何が起こりますか?つまり、./somefile some arguments
シェルに次のように入力してEnterキーを押すと(somefile
cwdに存在し、読み取り+実行権限がありますsomefile
)、後で何が起こりますか?
私アイデア正解は:
- シェルはシステムにシステムコールを実行して
exec
パスを渡します。somefile
- カーネルの確認
somefile
と参照マジックナンバープロセッサが処理できる形式であることを確認するためのファイルです。 - マジック番号がファイルがプロセッサが実行できる形式であることを示す場合
- 新しいプロセスの作成(プロセステーブルにエントリがあります)
somefile
メモリに読み込まれるかマップされます。スタックを作成し、コードのエントリポイントにジャンプを実行してから、パラメータsomefile
配列ARGV
(achar**
、["some","arguments"]
)で初期化します。
- マジックナンバーならシェルボーン次に、上記のように新しいプロセスを作成しますが、shebang(または)で参照し、次に渡されるインタプリタである実行可能
exec()
ファイルを使用します。/bin/bash
/bin/perl
somefile
STDIN
- ファイルに有効なマジック番号がない場合は、「無効なファイル(無効なマジック番号):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で処理されます。sh
dash
pstree
zsh
zexecve
Src/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
役に立つコメント(示されているように)タレジン):
一部のディスクファイルで定義されている単純なコマンドを実行します。
fork ()
- パイプ接続
- 検索コマンド
- リダイレクトする
execve ()
- 失敗した場合は、
execve
ファイルに実行モードが設定されていることを確認してください。その場合はディレクトリではなく、その内容はシェルスクリプトとして実行されます。
POSIX は、次の関数セットを定義します。exec(3)
機能、execve(2)
この機能をラップして提供します。ムル詳しくはお答えください。 Linuxでは、少なくともこれらの機能はカーネルではなくCライブラリによって実装されています。