【Linux】10日間でLPIC lv1の学習をしてLinuxの仕組みを理解してみた。


### 前置き、注意事項

- とある理由で短期集中でLPIC 101 102を一通り学習しました。
- 試験に受かるためというよりLinuxへの理解を深める、概念を掴む感じで学習しています。コマンドの暗記はしてない部分が多いです(101の範囲はPing-tさんでかなり覚えましたが、、、Ping-tさん面白い)

- 本記事ではLinuxが動作する仕組みについて現時点(2020/12/21)の自分なりの解釈をまとめてます、正直LinuxというよりOSとは何か？みたいな話しが多いですが。

- 自分の理解を深めるためにも、ものすごく初歩的な説明でもなるべく記述するようにしてます。(説明が冗長的すぎて嫌かも、、、それでも良いよ！と言う方は見ていって欲しいです！)

- 解釈間違えてる部分あるかもしれません、申し訳ございません、もし何かありましたら教えていただけますと幸いです。

###僕の学習前の知識
- mac OS 環境でのRailsでの開発でちょくちょくLinuxコマンドを叩くけど、意味はよくわかってない事が多い、プログラミング歴は７ヶ月ほどです。
- コンピュータサイエンスを学びたいと思いLPIC学習に入る直前１０日ほどで基本情報技術者試験の学習をしていた
 - 基本情報の学習教材
     - [キタミ式イラストIT塾 基本情報技術者 令和02年]( https://www.amazon.co.jp/dp/B082DT76Z8/ref=cm_sw_em_r_mt_dp_6C03FbKERZFA2?_encoding=UTF8&psc=1)
     - [～始めから効率よく学ぶ～ 基本情報技術者試験 最速 合格講座]( https://www.udemy.com/share/102JjmAEcZeV9RR3kH/)

###LPICの学習教材
- [Linux教科書 LPICレベル1 スピードマスター問題集 Version5.0対応] (https://www.amazon.co.jp/dp/4798160857/ref=cm_sw_em_r_mt_dp_-G03FbHZW6DH2)　(通称白本)
- [ping-tの最強WEB問題集](https://ping-t.com/)
- 適時用語をGoogle検索

###Linuxとは？

####二つの意味

狭義ではカーネル、広義ではOSのことです。

OSとはオペレーティングシステムの略でです、一言で言うとコンピュータの脳みたいなもの。これがないとコンピュータは動かない。
カーネルとは、OSの中核となるソフトウェア。

**厳密に言うとLinuxとはこのカーネルのことだけを指します。**では何故OSのこともLinuxと呼ぶのか？まずカーネルが何か説明します。

#### カーネルとは

**カーネルとはOSにとって、とても重要な役割をもつソフトウェアです。**でも、カーネルだけだとコンピュータは何もできません。（イメージで言うと１００人の部下を従えてチームを引っ張れるような人材を一人で働かせるような感じ）

ので、周りに優秀な部下（演算機能のあるソフトウェアとか）が必要です。
その部下をある程度OSとして動かせるチーム（ソフトウェア群)をLinuxカーネルを含めてまとめてLinuxディストリビュージョンまたは単にLinuxと言います、**つまりこれが広義でのLinuxなのです。**

ディストリビュージョンの日本語訳は配布、分布という意味でOS単位で一つのまとまりとして配布されています。



#### Linuxディストリビュージョン

Linuxディストリビュージョンはたくさんあります。無料で配布されているのものもあれば、有償のものもあります。

代表的なディストリビュージョン

- Red Hat Enterprise Linux (RHEL)
- Debian
- CentOS
- Ubuntu

まだまだありますが割愛します。


### LinuxOSは何をどうやってコンピュータを動かしているの？

まずはOSの役割から

####OSの役割

- コンピュータを起動
- 様々な演算
- 文字の入出力
- いろんなソフトウェアのインストール
- ソフトウェア、ミドルウェア、アプリケーションを操る
- 外部デバイスの接続
- インターネット通信
- 通信のセキュリティ確保

などなど、、、**コンピュータできることは必ずOSが絡んできます。**

どうやってその役割を担うのか？まずはコンピュータができることを説明します。

####そもそもコンピュータは
突き詰めると**0か１かスイッチの組み合わせ**を膨大に組み合わせてデジタルに物事を解釈、処理、出力しています。

#####どいうことか？
みなさんが今見ている文字にも色にも01つまり二進数で数字が割り振られていてそれを見てコンピュータは文字や色を解釈しています。
よく見るもので言うとカラーコード、例えば`#FFFFFF`これは白を意味するコードです（カラーコードは１６進数表記ですが１６進数は２進数に直すのは簡単です、ただすごく長い表現になります。）
16進数`FFFFFF`=2進数`111111111111111111111111`
こういう01の２進数だけで表現された言葉や命令を機械語なんて言ったりするらしいです。

コンピュータは英語や日本語は理解できず、機械語しか理解できなので、何かしてもらうには機械語で指示を出す必要があります。

でも、、01011100000……みたいな数字を打ちこみ続けてコンピュータを操作する人いませんよね


#### で結局、普通にいろいろ出来ているいるのはどういうこと？

- 人間のわかりやすい言葉で書かれたプログラミング言語を機械語に翻訳するインタプリタやコンパイラ
- コマンドによって該当のファイルを使ってプロセスを生成して、処理を行うCUIシェル
- システムコール、アプリケーション、パッケージ、、、

などなど、、、**いろんなツールやパッケージやアプリケーションなどがOSとコンピュータの仲立ちをしてくれている**おかげでコンピュータは動かせているわけです。

こういうことをLinuxカーネルと愉快な仲間たちが頑張ってやってくれているおかげでいろんな処理が実現しているんです。

ここで重要なのがファイルという考え方です。


### ファイル(ファイルシステム、FHS、パーティション)とは

####ファイル

ファイルはみなさんご存知の通りで、テキストファイルや画像ファイルなどいろいろなファイル形式があると思います。

ファイルは直接機械語で表されているものや、機械語表現に変換できたりするものがあります。

そして上記にでてきた**インタプリタやコンパイラ、アプリケーションも、全て対応しているファイルに記述された設定やアルゴリズム（演算手順）を使って動いています。**

つまりLinuxは様々な命令が書かれたファイルや情報の記載されたファイルを組み合わせてコンピュータを動かしているのです。**極端かもしれませんがソフトウェアもシステムコールもすべてはファイルなのです。**

でもファイルって抽象的ですよね、01しかできないコンピュータにどう理解保存させればいいのか？

####ファイルシステム

ファイルをHDD（ハードディスクドライブ）などの記憶領域にどういう形式で管理するのかを決めているのがファイルシステムです。

つまり、**コンピュータから見てファイルを並べるとただの0101000…..などの数字の羅列**なのでファイルとファイルの区切り方を決めてあげないとただのどこからどこまでがどのファイルなのか？ということが認識できないので**しっかり区切りけ方を決めようね**みたいなことです。

ファイルシステムもいろいろな方式が開発されていてLinuxではXFS、ext4などがあるみたいです。

このファイルシステムのおかげで抽象的なファイルという存在をコンピュータに理解してもえるわけです。

####パーティション

ファイルシステムを設定することで、HDDなどの記憶領域にファイルを保存できるようになりました！！となるわけではなく、、、
**実はファイルシステムを設定する前に、記憶領域を大きなくくりで分ける必要があります。**それがパーティション（区画）です。

パーティションとはHDDというでっかい家を何個かの部屋に分割する感じです、そうする事でそれぞれ部屋に役割を与えて(キッチン、リビング)そこに必要なファイル（家具、テーブル）をいれてあげる感じですね。

ちなみにパーティションにファイルシステムを設定することを**マウント**と言います。

####FHS

Linuxでは重要なファイル（コンピュータ起動に必要なファイル、ツールなど）はある程度どのディレクトリの中にどのファイルを入れるか決まっています、**これをFHS(ファイルシステムヒエラルキースタンダード)と言います。**

例えば /var/log にはログを保存するだとか、/etc には設定ファイルを保存するとか、ネーミングでわかりやすいように決まっています。Railsを勉強しててよく言われるRESTfullなんかに通じるものを感じました（違うかもしれませんが）

これを決めることで違ったディストリビュージョンとの互換性や、使用者がわかりやすいディレクトリ構造にするということが実現しているのです。


**カーネルはこういったしっかり管理されたファイル（ソフトウェア）を使って人間から指示されたことを実現しているんですね！**

では人間がカーネルに指示を出すのはどうやるか？、それを実現するのは次の項で。

###シェル UI(ユーザインタフェース)について

####シェルとは

シェル（殻）とはその名の通り『殻』です、なんの殻かというと、カーネルの殻です。
僕はポケモンのシェルダーをイメージしました。中の顔がカーネルということです。

こんな感じ、カーネルの周りをシェルが覆ってる
![9BF6FFDE-D9D7-4AE1-8608-DC0D68E6C68F_1_102_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653350/667da686-fcd0-9632-ea68-27b8e3a2ad63.jpeg)


**シェルは人間とカーネルの仲介を全方位からしてくれます。**なぜわざわざ仲介するのかというと、カーネルがとても大事だからです、下手に扱って壊れてしまうと大変なので、シェルというクッションを使ってカーネルと人間はコミュニケーションを図るわけです。

シェルにはCUIとGUIがあります

####CUIとGUI

これは知っているひとが多いと思いますが、

- CUIとはキャラクタユーザインタフェースの略です。
キャラクターは文字という意味があります
**その名の通り文字(キャラクタ)でユーザーとコンピュータがやりとりをするもの(ユーザインタフェース)なんですね。**
例えばbashというCUIシェルはユーザーはコマンドプロント(Macでいうターミナル)にコマンドを入力してカーネルをコミュニケーションをとります。

- GUIはお馴染みのマウスポインタなどを使ってグラフィカルに操作するやつですね。

#### コマンド （bash）

コマンドがコマンドプロンプトに打ち込まれて実行されると、シェルがコマンドを整形してシステムコールとしてカーネル渡して『プロセス』をが生みだされます、そしてその処理結果をまたコマンドプロンプトに返す。
というような流れで人間とカーネルがコミュニケーションをとります。

たとえば下記のようにlsコマンド(ディレクトリ下のサブディレクトリ名とファイル名を表示するコマンドを)を実行する

```
$ ls
fileA fileB
```
こんな感じの処理になります（とんでもなく字が汚い、、、）
![C3A4B9F7-B0AA-4222-99E5-0D678A93C08A_1_102_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653350/9912e81e-ee8e-11b6-e84e-ad4b19df25c3.jpeg)


画像の中にコマンド実行ファイル(シェルスクリプト)とあります。
シェルスクリプトとはコマンドの処理について書かれたファイルなのです、**そう、全てはファイルなのです。(多分)**
というわけで**シェルとシェルスクリプトは似た言葉ですがまったく別の意味なので注意が必要です。**

lsコマンドにもシェルスクリプトがあります、コマンドが実行されると環境変数の$PATHに入っているパスを参考にどこに該当のシェルスクリプトがあるか探しに行きます。

whichコマンドを使うと引数（コマンドにくっつけるやつ）で指定したコマンドのシェルスクリプトの場所がわかります。

```
$ which ls
/bin/ls
```

#### 環境変数 シェル変数

変数っていうのはプログラミング言語における値を入れる箱です、プログラミングを勉強してると良く出てきますよね。

- 環境変数はコンピュータ全体で使えるもの。

- シェル変数はそのプロセスだけでしか使えないもの。（子プロセスでは使えない）

プロセスというのはシェル、カーネルよって実行される処理のことです。
実はシェル自身もプロセスだったりします。そう、**全てはプロセスなのです。(多分)**
**コマンドの実行とは、シェルという親プロセスから子プロセスを生成するということなのです。**

まぁちょっとややこしいんですけど、**環境変数はコンピュータの設定みたいなものですね。**ちょっと違うかもですが。

環境変数の$PATHはコマンドを探しに行く場所をいれてる変数です！

#### パッケージ、ライブラリ

パッケージとはある動作に必要な各種プログラムやファイルをまとめたものである。
ライブラリも似たようなものです、プログラム、ファイルのことです。**そう全てはファイルなのです。（言いたいだけ）**
パッケージ管理（外部からインストールしたりアップデートしたり）のためのパッケージもあります。

例えばAPTツールはLinuxディストリビュージョンで公式にサポートされているパッケージを全部持ってる「公式リポジトリ」に入っているパッケージをインストールしたりできます。

hogehogeをインストールしたいときは

```
$ apt-get install hogehoge
```

みたいに使います。

###まとめ

長々と書きましたがつまりLinuxの動く仕組みは

**シェルを仲介してきた命令をカーネルが受け、そしてカーネルがアプリケーション、ソフトウェア、シェルスクリプトという名のファイル群などを活用し、結果を返す。**

ざっくりこんな仕組みです！
この概念をなんとなくつかめているとプログラミングでもLPICの試験勉強をする場合でも理解がしやすくなるのでは？と思います。

少しでも誰かの助けになれば幸いです。
最後まで読んでいただきありがとうございましたm(__)m