シェルには、他のコマンドと同じ標準入力、標準出力、標準エラーがありますか?

シェルには、他のコマンドと同じ標準入力、標準出力、標準エラーがありますか?

たとえば、bashは/bin/bashの下にあります。これはコマンドであることを意味し、各コマンドには標準入力、標準出力、標準エラーの3つの(0,1,2)穴があります。

これがシェルにも100%本当ですか?それとも、コマンドやプロセスとしてのシェルの特別な意味のために別のものですか?

答え1

他のプログラムと同じです。これにより、他のプログラムと同様に、I/O をリダイレクトしてパイプすることができます。

echo "cat filename" | bash

コマンドはパイプから標準入力を読み取ると実行されますcat filenamebash

bash -c "echo foo" > filename

コマンドecho fooが実行され、出力がファイルにリダイレクトされます。

Unixでは、シェルに「特別な」ものはありません。これは、他のプログラムを実行することが主な目的である一般的なプログラムです。

答え2

いくつかの用語を区別してみましょう。

注文するシェルに入力する内容です。それニックネームまたはシェル機能、または以下を参照することもできます。実行可能ファイル

一つ実行可能ファイルすることができますバイナリ実行可能ファイル(つまり、機械語コードを直接含むコード)またはスクリプト。スクリプトには、bashスクリプト、shスクリプト、perlスクリプト、awkスクリプト、sedスクリプト、pythonスクリプトなどが含まれます。他。

スクリプトの最初の2バイト(実行ファイルとして直接実行される場合)は必要です#!。これは、改行文字を読み込むまでカーネルにさらにバイトを読み取るように信号を送る「魔法の数」です。 ㅏバイナリ実行可能ファイル、スペースで区切られた1つの引数(たとえば#!/bin/awk -f)を持つことができ、次のように実行します。それバイナリ実行可能ファイル、スクリプト自体のパスがパラメータとして渡されます。

最終的にカーネルが実際に実行できる唯一のものはバイナリ実行ファイルである機械語コードだけです。 sh、bash、perl、python、awkなどのバイナリ実行可能ファイルです。他。 ~と呼ばれる通訳者。 彼らはスクリプトを解釈し、その指示を実行します。ただし、実行するには機械語コード自体に存在する必要があります。

プログラム(バイナリ実行可能ファイル)が実際にカーネルによって実行されると、次のように動作します。プロセス。 バイナリ実行可能ファイルは命令を含むファイルにすぎません。 ㅏプロセスより具体的には「プログラムの実行インスタンス」であり、関連するメモリ、環境変数、プロセスID(PID)とともにカーネルに組み込まれた抽象化です。ファイル記述子入出力だけでなく、その他の属性にも使用できます。実行可能ファイルを「同時に」複数回実行できます(実際にはシングルコアシステムでは同時にではありませんが、カーネルがCPUサイクルを割り当てる方法によって〜らしい同時に)実行中の各インスタンスは、すべて同じプログラムのインスタンスであっても異なるプロセスになります。

0、1、2(標準入力、標準出力、標準誤差)はファイル記述子。 正直なところ、彼らは慣習によってのみ存在します。 Cを使用すると、これらのファイル記述子を指定せずに他のプログラムを起動(実行)(さまざまなバイナリ実行可能ファイルを実行)するプログラムを作成できます。 しかし、標準プログラムはファイル記述子0、1、2を使用できるという前提で作成されているため、おそらくエラーが発生し(ほとんどの場合)、プログラムが正しく機能しません。

これを完全に理解するには、以下を理解する必要があります。プロセスが発生する方法。 一種の誕生の奇跡と同じです。 ;) すべてのプロセスは、次のように実行する必要があります。その他プロセス。システムの起動時に最初のプロセスがどのように起動するのか心配しないでください。 PID 1を持つプロセスは「init」と呼ばれ、オペレーティングシステムの実行に必要なその他の基本プロセスを起動します。

プロセスが別のプロセスを開始する方法には、2つの基本的なステップがあります。クロスそして実装する。 どちらもシステムコールです。つまり、プロセスが送信したジョブ/要求です。カーネルでカーネルだけがこれを実際に達成できます。

「フォーク」は(簡単に)「カーネル、コピーを作ってください」を意味します。 (「Me」は実行中のプロセスです。)カーネルは、プロセスのファイル記述子、メモリ、実行状態(インスタンスインプログラムを構成するコマンドに従う間にあった場所)、環境などのプロセスの完全なコピーを作成します。変数など。したがって、これはそのプロセスの「コピー」です。さて、オリジナルとコピーをどのように区別しますか? 1つだけ:システムコールの戻り状態ですfork。子プロセスは「0」(成功)を取得し、親プロセスは新しく作成された子プロセスのPIDを取得します。したがって、この戻り状態を確認することで、各プロセスは今何をすべきかを理解することができます(同じ命令セットに従うことに注意してください!)。

「Exec」は実際には「execve()」です。簡単に言えば、カーネルに「カーネルをお願いします。変える私(私はプロセスです)は______ファイルにプログラムインスタンスを指定しました。 「そしてプログラマーも指定しました。議論新しいプロセスに環境(環境変数の配列)があります。

したがって、シェルにコマンドを入力すると実際に発生するのは(ほとんどの場合はシェル組み込みなどの特殊なケースを無視してcd)シェル(実行中のプロセス)です。フォーク、それから役員ユーザーが指定するコマンドです。

出力または入力リダイレクトを実行した場合の/bin/echo hello > /dev/nullフォークされたサブプロセスexecエコをする前にファイル記述子 1 (この場合) が/dev/null端末または以前の端末の代わりにバインドされるように、ファイル記述子を適切に調整します。

したがって、実行中の実行可能ファイルインスタンスには、/bin/bash使用可能なファイル記述子0(入力を読み取ることができる)、ファイル記述子1(出力を書き込むことができる)、およびファイル記述子2(出力を読み取ることができる)があると予想されます。作成)エラー)メッセージと同様の入力/出力を読み書きします。

関連情報