cd
シェルで入力したとしましょう。されcd
、その時点でメモリからロード?私の直感は、これらの組み込みコマンドはカーネルがロードされた後にシステムメモリにプリロードされることですが、誰かが実際にコマンドを起動したときにのみロードされると主張しました(シェルでEnterキーを押します)。これを説明する参照があるかどうか教えていただけませんか?
cd
シェルで入力したとしましょう。されcd
、その時点でメモリからロード?私の直感は、これらの組み込みコマンドはカーネルがロードされた後にシステムメモリにプリロードされることですが、誰かが実際にコマンドを起動したときにのみロードされると主張しました(シェルでEnterキーを押します)。これを説明する参照があるかどうか教えていただけませんか?
回答:
シェルにcdと入力したとしましょう。現時点でCDはメモリから読み込まれていますか?私の直感は、これらの組み込みコマンドはカーネルがロードされた後にシステムメモリにプリロードされるということですが、誰かが実際にコマンドを呼び出すときにのみロードされると主張しました...
大まかに言えば、他の答えは正しいです-組み込みはシェルで読み込まれ、スタンドアロンは呼び出されたときに読み込まれます。ただし、非常に粘着性のあるイタチのような「誰か」は、それがそれほど単純ではないと主張することができます。
この議論は、OSがどのように機能するか、OSの機能がどのように異なるかについていくらか述べられていますが、一般的に、以下はすべての現代の* nixに当てはまると思います。
まず、「メモリに読み込まれる」という表現はあいまいです。実際に私たちが言及しているのは、その仮想アドレス空間がメモリにマッピングされていることです。「仮想アドレス空間」はメモリに配置する必要があるかもしれないものを指すため、これは重要ですが、実際には最初はそうではありません。ほとんどの場合、実際にメモリにロードされるのはマップ自体であり、マップは領域ではありません。 「テリトリー」は、ディスク(またはディスクキャッシュ)の実行可能ファイルであり、実際には、実行可能ファイルを呼び出しても、そのほとんどはメモリに読み込まれません。
また、「テリトリー」の多くは他のテリトリー(共有ライブラリ)への参照であり、繰り返しになりますが、それらが参照されているからといって、実際にロードされているわけでもありません。それらは実際に使用されるまでロードされません。その後、「使用」が成功するために実際にロードする必要のある部分のみがロードされます。
たとえばtop
、bash
インスタンスを参照するLinux の出力のスニペットは次のとおりです。
VIRT RES SHR S %CPU %MEM TIME+ COMMAND
113m 3672 1796 S 0.0 0.1 0:00.07 bash
113 MBのVIRTは仮想アドレス空間であり、RAMにマップされます。しかし、RESはプロセスによって消費される実際のRAMの量です-わずか3.7 kB。そして、そのうちのいくつかは、上記の共有領域の一部です-1.8 kB SHR。しかし、私の/bin/bash
ディスク上の私は930 kBであり、それがリンクする基本的なlibc(共有ライブラリ)は再び2倍の大きさになります。
そのシェルは現在何もしていません。組み込みコマンドを呼び出すとしましょう。これは、前に言ったように、シェルの他の部分とともにすでに「メモリにロードされています」。-コードは、マップ内の時点で関与開始され、そしてそれは本当にロードされていないコードへの参照に達したときに、それをロードするものは何でも、カーネルが実行ディスク上の実行可能イメージから -にもかかわらず、よりカジュアルにつまり、その実行可能ファイル(シェル、スタンドアロンツール、または共有ライブラリ)は既に "メモリに読み込まれています"。
これはデマンドページングと呼ばれます。
次の実験を行って、組み込みコマンドが実際に実行可能ファイルの一部としてロードされることを示しましたbash
。それがビルトインと呼ばれている理由ですが、デモは常に何かを証明するための最良の方法です。
新しいbash
シェルを起動し、そのプロセスID(PID)をメモします。
$ bash
$ echo $$
6402
2番目のターミナルでps
コマンドを実行しbash
て、追加のメモリの使用が開始されるかどうかを確認します。
$ watch "ps -Fp 6402"
出力は次のようになります。
Every 2.0s: ps -Fp 6402 Sat Sep 14 14:40:49 2013
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
saml 6402 6349 0 28747 6380 1 14:33 pts/38 00:00:00 bash
注:メモリ使用量は、SZおよびRSS列とともにここに表示されます。
シェル(pid 6402)でコマンドの実行を開始します。
あなたにcd
あなたの周りには、実際に上がるんメモリに気付くでしょうが、これが原因で、実行可能ではないcd
メモリにロードされたディスク上のディレクトリ構造がメモリにロード取得されているので、むしろこれがあります。あなたが続ける場合はcd
、他のディレクトリに」INGをあなたはそれがインクリメンタルに上がり続ける表示されます。
Every 2.0s: ps -Fp 30208 Sat Sep 14 15:11:22 2013
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
saml 30208 6349 0 28780 6492 0 15:09 pts/38 00:00:00 bash
次のように、より複雑なテストを実行できます。
$ for i in `seq 1000`; do cd ..; cd 90609;done
このコマンドは、レベルをcdしてから、ディレクトリ90609に1000回戻ります。これを実行している間、ps
ウィンドウでメモリ使用量を監視すると、変化しないことがわかります。このようなものを実行している間、追加のメモリ使用量に気付くべきではありません。
strace
これはbash
、実際の実行可能ファイルではなく組み込み関数を扱っていることを示しています。実行しようとするstrace cd ..
と、次のメッセージが表示されます。
$ strace cd ..
strace: cd: command not found
「組み込みコマンド」とは、個別のプログラムとしてではなく、シェルに組み込まれたコマンドを指します。ls
たとえば、実際には組み込みコマンドではなく、別個のプログラムです。すでにディスクキャッシュにある場合を除き、起動時にRAMに読み込まれます。
組み込みコマンドの例は、printf
またはcd
です。これらはシェルの一部であり、残りのシェルと共にロードされます。
これを行うためにシステムが作成されていますが、デフォルトではコマンドはプリロードされていません。