web-dev-qa-db-ja.com

なぜCDはプログラムではないのですか?

なぜcdがプログラムではないのかといつも疑問に思っていましたが、どうにかして答えを見つけることができませんでした。

これが事実である理由を誰かが知っていますか?

131
AkshaiShah

cdコマンドは、「現在の作業ディレクトリ」を変更しますよね?

「現在の作業ディレクトリ」は、各プロセスに固有のプロパティです。

したがって、cdがプログラムの場合、次のように機能します。

  1. cd foo
  2. cdプロセスが開始します
  3. cdプロセスはディレクトリを変更しますcdプロセスの場合
  4. cdプロセスが終了します
  5. シェルの状態は、現在の作業ディレクトリを含め、開始前と同じです。
173
Daniel Pittman

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が最初に実装された後、予期せず動作しなくなりました。

引用Dennis Ritchie

歓喜の最中に、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は無効になります。したがって、シェルによって認識および実行されます。

108
jlliagre

Bashの紹介から( シェルとは? ):

シェルはまた、個別のユーティリティを介して取得することが不可能または不便な機能を実装する組み込みコマンド(ビルトイン)の小さなセットを提供します。たとえば、cdbreakcontinue、およびexec)は、シェル自体を直接操作するため、シェルの外部では実装できません。 historygetoptskill、またはpwdビルトインは、別のユーティリティで実装できますが、ビルトインとして使用する方が便利ですコマンド。シェルのすべてのビルトインについては、後続のセクションで説明します。

47
cjc

今年のエイプリルフールのために、私は cdのスタンドアロンバージョン を書きました。

誰も冗談を聞きませんでした。はぁ。

cdをシェルにビルドする必要があるかどうかわからない場合は、ダウンロードしてビルドし、試してみてください。

マニュアルページも読んでください。 :)

29
Warren Young

シェルのcdコマンドを個別のプロセスにすることはできません。Unixでは、別のプロセス(親プロセスでさえも)の現在の作業ディレクトリを変更するメカニズムがないためです。

cdが別のプロセスだった場合、その親(シェル)の現在の作業ディレクトリを変更する必要があります。これは、Unixでは不可能です。代わりに、cdは特別な組み込みコマンドです。シェルはchdir()fchdir()などの関数を呼び出して、自身の現在の作業ディレクトリを変更します。

注:カーネルは、すべてのプロセスの現在の作業ディレクトリのiノード番号を保存します。子プロセスは、その親からcwdを継承します。

4
saurav1405

cdはシェルの組み込みコマンドです。簡単です。男CDはそれをすべて言います。 cdコマンドは、すべてのインタープリターおよび(スレッド環境では)すべてのスレッドの作業ディレクトリーを変更します。

0
user18925