問題意識
長くて難しそうな英語の文章を見かけると、すぐGoogle翻訳にかける。
プログラミング中、問題に遭遇すると、すぐにQiitaやStackOverflowで検索する。
それでは、翻訳・検索をする作業者に過ぎない。翻訳・検索API。
しかし、問題にぶち当たった時、単なる作業人に陥ってしまっていることが多々ある。
ターミナルでlsコマンドやcdコマンドを使うことはしょっちゅうある。
しかし、内部で何が起こっているのかをどれほど理解しているのか。
確かに、自動車の仕組みを知らなくても運転できるし、
ユニクロがなぜ高機能で低価格なのかも知らずに買って着ることができる。
だが、ここで問題にしたいのはあなたは単なる作業人に甘んじてしまっていいのですか、ということだ。
これを思ったきっかけは、とある参考書でUbuntuを触る機会があり、よく
sudo apt-get update
sudo apt-get upgrade
が出てきて、私は何の疑問も持たずに上記のコマンドをベチベチ打っていたことに、気づいたことだ。
上記のコマンドを打つと、滝のように文字列がターミナルにダダダダと流れていくのだが、これ一体何が起こってるん?
そもそも、コマンドを入力したときに内部で何が起こってるん?
私は、なぜJKがTikTokにハマり、なぜ韓国嫌いな祖母が韓ドラにハマっているのか、
その仕組みについては興味がないのだが、このことについては興味がある。
だから深掘りしていこう。
深掘り
まず、ターミナルにコマンドを打った時、内部で何が起こっているのか。
前提として、ターミナルとシェルは違っていて、
ターミナルは、GUI上でCUIの操作をしたい時に使用するアプリケーションであり、実際に命令を解釈しOSへ伝達する役割はシェルが担っている。
つまり、コマンドを実際に解釈しているのはシェルである。
さらに踏まえておきたいのは、シェルによって解釈されたコマンドの実態はC言語で書かれたプログラムであり、そのプログラムの中身でカーネルのシステムコールが呼び出され、各種処理(ファイル操作、プロセス操作)が実行される、ということだ。
ということは、例えばlsコマンドを入力した時に、lsコマンドが意味する内容をもつ、C言語のプログラムが実行されるということだろうか。
そこで、以下の記事にあたったのだが、
これが、難しい。
ここでは、上の記事で触れられている、コマンドのオプションやgetopt関数については触れない。
しかし、確かに、ls.cというCプログラムをコンパイルして得られた実行ファイルが存在し、
コマンドのオプションに応じて結果を標準出力するようだ。
同様にcdコマンドについても、実行ファイルが存在する。
私はMac使いだが、コマンドの実行ファイルを探すwhichコマンドで、
which cd
を実行すると、
cd: shell built-in command
と出る。
一方で、
which ls
では、
/bin/ls
である。
この違いは、cdはシェルの組み込みコマンドである一方で、lsは組み込みコマンドではないという理由であるが、本線から外れるので、そっとしておく。
とにかく、lsの実行ファイルは、/bin/lsに存在することがわかった。
/bin/には他にも、コマンドの実行ファイルが存在している。
しかし、疑問は尽きない。
なぜ、コンパイル後の実行ファイルが存在しているのか。
実行ファイルではなく、Cプログラムを置いておいて、
ターミナルにコマンドのオプションや引数を入力した時に、それをCプログラムが受け取り、その都度コンパイルし、実行ファイルを呼び出すのではダメなのか。
コンパイル後の実行ファイルがどのようにして、オプションや引数を解釈するのか。
また、そもそもターミナルに入力された"ls"という文字列はどのように解釈されているのだろうか。
次回に持ち越し。
参考記事