なぜcd
がプログラムではないのかといつも疑問に思っていましたが、どうにかして答えを見つけることができませんでした。
これが事実である理由を誰かが知っていますか?
cd
コマンドは、「現在の作業ディレクトリ」を変更しますよね?
「現在の作業ディレクトリ」は、各プロセスに固有のプロパティです。
したがって、cd
がプログラムの場合、次のように機能します。
cd foo
cd
プロセスが開始しますcd
プロセスはディレクトリを変更しますcdプロセスの場合cd
プロセスが終了しますcd
は、Shellビルトインであることに加えて、は実際にはPOSIX準拠OS上のプログラムでもあります。それらは 必須cd
のような通常のユーティリティに独立した実行可能ファイルを提供します。これは、たとえば Solaris 、 [〜#〜] aix [〜#〜] 、HP-UXおよび OS X の場合です。
明らかに、組み込みのcd
は、その外部実装が現在のシェルディレクトリを変更しないため、依然として必須です。ただし、後者は依然として有用です。以下は、このcd
コマンドの使用方法をPOSIXがどのように想定するかを示す例です。
find . -type d -exec cd {} \;
POSIXシステムでは、このonelinerはcd
で許可されていないすべてのディレクトリのエラーメッセージを報告します。ほとんどのGnu/Linuxディストリビューションでは、次のエラーメッセージで失敗します:
find: `cd': No such file or directory
そして、これがあなたの質問への答えです、元のUnix共著者の一人による "なぜCDはプログラムではないのですか?"。非常に初期のUnix実装では、cd
(当時はchdir
と表記)は外部プログラムでした。 fork
が最初に実装された後、予期せず動作しなくなりました。
歓喜の最中に、chdir(現在のディレクトリの変更)コマンドが機能しなくなったことが発見されました。多くのコードを読み、forkを追加するとchdir呼び出しが壊れる可能性があることを心配して内省しました。ついに真実が明らかになった:古いシステムではchdirは普通のコマンドだった。端末に接続されている(一意の)プロセスの現在のディレクトリを調整しました。新しいシステムでは、chdirコマンドは、それを実行するために作成されたプロセスの現在のディレクトリを正しく変更しましたが、このプロセスは即座に終了し、親シェルには何の影響もありませんでした! chdirをシェル内部で実行される特別なコマンドにする必要がありました。いくつかのコマンドのような関数は、たとえばログインなど、同じプロパティを持っていることがわかります。
出典:Dennis M. Ritchie、「 The Evolution of the Unix Time-sharing System 」、AT&T Bell Laboratories Technical Journal 63 (6)、パート2、1984年10月、pp.1577–93
Unixバージョン1(1971年3月)chdir manual page の状態:
各コマンドを実行するための新しいプロセスが作成されるため、通常のコマンドとして作成されたchdirは無効になります。したがって、シェルによって認識および実行されます。
Bashの紹介から( シェルとは? ):
シェルはまた、個別のユーティリティを介して取得することが不可能または不便な機能を実装する組み込みコマンド(ビルトイン)の小さなセットを提供します。たとえば、
cd
、break
、continue
、およびexec
)は、シェル自体を直接操作するため、シェルの外部では実装できません。history
、getopts
、kill
、またはpwd
ビルトインは、別のユーティリティで実装できますが、ビルトインとして使用する方が便利ですコマンド。シェルのすべてのビルトインについては、後続のセクションで説明します。
今年のエイプリルフールのために、私は cd
のスタンドアロンバージョン を書きました。
誰も冗談を聞きませんでした。はぁ。
cd
をシェルにビルドする必要があるかどうかわからない場合は、ダウンロードしてビルドし、試してみてください。
マニュアルページも読んでください。 :)
シェルのcd
コマンドを個別のプロセスにすることはできません。Unixでは、別のプロセス(親プロセスでさえも)の現在の作業ディレクトリを変更するメカニズムがないためです。
cd
が別のプロセスだった場合、その親(シェル)の現在の作業ディレクトリを変更する必要があります。これは、Unixでは不可能です。代わりに、cd
は特別な組み込みコマンドです。シェルはchdir()
やfchdir()
などの関数を呼び出して、自身の現在の作業ディレクトリを変更します。
注:カーネルは、すべてのプロセスの現在の作業ディレクトリのiノード番号を保存します。子プロセスは、その親からcwd
を継承します。
cdはシェルの組み込みコマンドです。簡単です。男CDはそれをすべて言います。 cdコマンドは、すべてのインタープリターおよび(スレッド環境では)すべてのスレッドの作業ディレクトリーを変更します。