健全性チェック:私が理解している限りでは、シェルは、ユーザーが OS とやり取りできるインターフェイスです。つまり、他のプロセスを実行します。
はい。ただし、「シェル」は具体的にはユーザーです インターフェイスであり、プログラミング インターフェイスではありません。他のプログラムは、それと対話する必要はありません。同じシステム コールを直接使用して、新しいプロセスを作成できます。
そのため、コマンドライン シェルは他のプログラムと同じレベルにあります。サービス マネージャー、またはグラフィカル ユーザー インターフェイス (グラフィカル シェル)。
<ブロック引用>ただし、シェル (Bash など) は単なる別のプロセスです。
はい。 Unix ライクなシステムでは、これは完全に通常の非特権プロセスです。
<ブロック引用>シェル プロセスの子にならないプロセスを実行する方法はありますか?
ユーザーの観点から:はい、いくつかの方法があります。
-
ほとんどのシェルには
exec
があります 新しいプログラムを置き換えるキーワード シェル (同じ PID と親子関係を保持)。これはおそらくあなたが意図したものではありませんが、技術的にはあなたが求めていたものです. -
多くの場合、グラフィカル デスクトップ セッションは、bash やその他のシェルを呼び出さずに開始されます。これは、グラフィカル メニューから起動されたアプリに自動的に適用されます。アプリの親は、メニューの表示を担当するプロセス (ウィンドウ マネージャーやパネルなど) になります。
-
現在人気のある systemd init システムは、サービスの開始時にシェルをまったく使用しないため、.service を定義して開始できます。サービスの親は init 自体になります。
systemd-run
を使用してオンザフライで一時的なサービスを作成できる機能もあります。 、同じ結果になります。
プログラマーの観点からは、 fork()
を使用するだけです と execve()
新しいプロセスを起動するためのシステム コール。 (OS 固有の詳細があります。たとえば、fork() は実際には別の呼び出しのラッパーである可能性がありますが、それでも同じように機能します。)
実際、プログラムがシェルを呼び出したい場合でも、新しい子プロセスを作成し、同じ fork+exec を使用して /bin/sh を実行することで実行します。シェルを実行するための特別なシステム コールはありません。 (プログラマーは、たとえば、C で記述するときに system() を使用したり、Python で os.system() を使用したりできますが、これらは fork/exec の便利なラッパーにすぎません。)
<ブロック引用>環境変数:bash には、シェルを生成するときに実行されるスクリプトがいくつかあります。 .bashrc、.bash_profile など (シェルのタイプによって異なります - インタラクティブか非インタラクティブか、ログインか非ログインか)。これらのスクリプトは、環境変数を定義します。シェルに関係なくプロセスを実行する方法がある場合、環境変数はどこから来るのですか?
まあ、そうでない場合もあります。 (特定のグラフィカル環境の起動方法に応じて、グラフィカル アプリに環境のカスタマイズを反映させようとする場合、これは現実的な問題です。)
ただし、全体として、環境変数はそうではありません CLI シェルに固有です。各プロセスは、開始方法に関係なく (init プロセスを含む)、コマンド ラインを含む文字列の配列と、環境変数を含む文字列の配列を受け取ります。子プロセスを起動するとき、別の環境を指定するか、独自の環境のコピーを継承できるようにすることができます。
したがって、ログインすると、シェルはすでに親からいくつかの初期環境変数を受け取っています。これらの起動スクリプト (bashrc など) は、ユーザーがシェルの子プロセスが継承する環境変数をカスタマイズするための便利な場所です。
この回答の多くの部分は、Windows にも完全に当てはまります。Windows のグラフィカル インターフェイスはもう少し複雑ですが、CLI シェル (cmd.exe と PowerShell) は通常の操作ではまったく使用されない通常のプログラムです。唯一の大きな違いは、Unix スタイルの個別の「fork + exec」呼び出しの代わりに、Windows には単一の「CreateProcess」呼び出しがあることです。
<オール>
それは正しいです。最終的に、シェルは exec
を実行します システム コールは、すべての POSIX 準拠のオペレーティング システムで使用でき、より一般的には、Linux を含むすべての Unix ライクなオペレーティング システムで使用できます。他のオペレーティング システムにも同様の概念があります。 Linux では、exec
システムコールは最終的に execve
を呼び出します 関数はカーネルによって提供され、実行可能ファイルをロードして実行する実際のジョブを実行します。
はい。どのプロセスでも exec
を呼び出すことができます 、「シェル」である必要はありません。たとえば、ファイルシステム ブラウザをクリックしてプログラムを起動すると、デスクトップ ソフトウェアが exec
を実行します。 呼び出し、シェルはありません。プロセスは、それを起動したデスクトップ ソフトウェアの子になることに注意してください。 init
と呼ばれる最初のプロセスを除いて、すべてのプロセスは他の 1 つのプロセスの子プロセスです。 PID 1 を持っています。起動時にオペレーティング システムをセットアップし、バックグラウンド サービスやデスクトップ ログインなどの他のすべてのプロセスを起動します。最近の Linux では、systemd
init
としてよく使われます プロセスですが、他の代替手段があります。
exec
にはいくつかのバリエーションがあります (execl
、 execle
、...) 実行するプログラムの名前に加えて、さまざまな引数があります。最終的に、execve
システムコールは、プログラム名、コマンドライン引数である文字列のリスト、および環境変数である文字列のリストを取ります。たとえば、ファイルシステム ブラウザからソフトウェアを起動する場合、環境変数はファイルシステム ブラウザ自体のものからコピーされ、ファイルシステム ブラウザによって変更される可能性があります。これは完全にファイルシステム ブラウザのプログラマ次第です。
さらに読む:
- https://en.wikipedia.org/wiki/Exec_(system_call)
- https://en.wikipedia.org/wiki/Fork%E2%80%93exec
- https://man7.org/linux/man-pages/man2/execve.2.html