Linux基礎まとめ

Linuxについてざっくりまとめました。

## Linuxとは
オープンソースのOSで、サーバーによく使われる。要はアプリを動かすための土台を作ること。
長く使われている技術なので一度覚えると便利。

OSとはオペレーションシステムの略で、コンピュータの基本操作を提供するソフトウェアのこと。コンピュータを動かすためにはこのOSが必須になる。Linuxの他にもMacOSやWindowsなどがある。

Linuxは狭義の意味ではLinuxカーネルを指し、広義の意味ではLinuxディストリビューションを指す。


## Linuxの仕組み
### カーネル
カーネルとはLinuxの中核のソフトウェアのこと。

### ディストリビューション
ディストリビューションとはカーネルに様々な機能を加えてOSとして使いやすくしたもの。

実際にLinuxを使う時はこのディストリビューションをインストールして使う。

ディストリビューションは大きく分けてRedhat系とDebian系の2つの種類がある。よく使われるのがRedhat系のCentOS、Debian系のUbuntu。

### シェル
シェルはLinuxのCLIを提供するソフトウェア。CLIとはキーボードからコマンドを入力して文字列として結果を出力するインタフェース。

Linuxを操作するには、シェルでコマンドを入力してカーネルに伝え、カーネルはコマンドを実行しその結果をシェルで表示する。

:::note warn
シェルとMacのターミナルは別物。シェルはコマンドを解釈するソフトウェアで、ターミナルは入出力の画面を提供するソフトウェアであり、ターミナルの中でシェルが動いている。
:::

シェルにはsh、bash、zshなど複数の種類があり、よく使われるのはbashとzsh。

shが最も古いシェルで機能は少ないが標準的なシェルであり、bashやzshはshの機能を拡張したシェルである。


## ディレクトリ構造
ディレクトリとは、Windowsでいうフォルダのことでファイルを保存する場所。利用目的ごとにファイルをまとめたり、ディレクトリを保存することができる。

### ディレクトリの種類
Linuxの主なディレクトリの種類。

#### /
`/`はルートディレクトリを表す。ルートディレクトリとはLinuxの大元のディレクトリで、このディレクトリから入れ子構造となってさまざまなディレクトリやファイルが構成される。

#### /etc
`/etc`はLinuxの設定ファイルを格納するディレクトリ。Linuxで動作するアプリの設定ファイルも格納される。


#### /home
`/home`はユーザーごとに割り当てられる個別のディレクトリを格納するディレクトリ。基本的にどんなファイルも置くことができる。

#### /root
`/root`は管理ユーザーのホームディレクトリ。

#### /bin
`/bin`はコマンドの実行ファイルを格納するディレクトリ。binはbinariesの略。

#### /sbin
`/sbin`は再起動やシャットダウンなど管理ユーザー向けのコマンドの実行ファイルを格納するディレクトリ。


#### /tmp
`/tmp`は一時的なファイルを格納するディレクトリ。このディレクトリの中にあるファイルはパソコンを再起動すると消えてしまうので注意。

#### /var
`/var`はログやキャッシュなどの一時的なデータを格納するディレクトリ。`/tmp`と異なり、パソコンを再起動しても消えない。


#### /usr
`/usr`は各ユーザーが利用するプログラムを格納するディレクトリ。

#### /dev
`/dev`はハードウェアをファイルとして扱えるようにしたデバイスファイルを格納するディレクトリ。

#### /opt
`/opt`は自分でインストールしたアプリなどを格納するディレクトリ。パッケージマネージャを使わずにアプリをインストールした場合はこのディレクトリに保存する。



## コマンド
コマンドとは、Linuxカーネルを操作するためのシェルに入力する命令のこと。
コマンドの後ろにハイフン＋何らかの記号を付け加えることでオプションを与えることができる。

### 基本のコマンド

#### cd
change directoryの略で、ディレクトリを移動するコマンド。
```
// 指定したディレクトリに移動
cd [ディレクトリ名]

// ホームディレクトリに移動
cd ~ 

// ルートディレクトリに移動
cd / 

// 一つ前のディレクトリに移動
cd ../

// 何も指定しなければホームディレクトリに移動
cd
```

#### pwd
print name of working directoryの略で、カレントディレクトリのパスを表示するコマンド。

```
// カレントディレクトリを表示
pwd
```

#### ls
listの略でディレクトリの中のファイルやディレクトリを一覧で表示するコマンド。

```
// カレントディレクトリの中身を表示
ls

// homeディレクトリの中身を表示
ls home

// 隠しファイルも含めた全てのファイルとディレクトリを表示
ls -a 

// ファイル、ディレクトリの詳細情報を表示する
ls -l

// ファイル種別を表示する
ls -F
```

オプションはまとめて実行することもできる
```
// すべてのファイルの詳細情報を表示する
ls -la
```

#### mkdir
make directoryの略で、ディレクトリを作成するコマンド。

```
// homeディレクトリを作成
mkdir home
```

#### rmdir
remove directoryの略で、空のディレクトリを削除するコマンド。
ディレクトリが空でなければ`Directory not empty`というエラーが表示される。

```
// homeディレクトリを削除する
rmdir home
```



### コマンドの仕組み
コマンドの実体はプログラムが書かれたバイナリファイルである。

コマンドを実行することは、そのコマンドのファイルのパスを指定してプログラムを実行していることになる。フルパスで入力しなくてもコマンドが実行されるのは、環境変数の`PATH`にコマンドのパスが格納されているからである。

コマンドのフルパスを環境変数`PATH`に格納してコマンド名だけで実行できるようにすることを`パスを通す`という。

`which`コマンドを使えばコマンドのパスを表示できる。
```
which [コマンド名]
```


## 環境変数
環境変数とはOSが動いている時に使える変数のこと。コンピュータに保存されているのでどのシェルでも使える。

反対に実行しているシェルでしか使えない変数をシェル変数という。

### 環境変数を定義する
環境変数を定義するには`export`コマンドを使う。

```
export [環境変数名]=[値]
```

### 環境変数を参照する
#### env
`env`コマンドで環境変数を一覧表示できる。

```
env
```

#### echo
`echo`コマンドで特定の変数を表示できる。

```
echo [環境変数]
```




## ファイル
Linuxでは設定情報をファイルで管理する。ファイルとはコンピュータの中でデータを保存しておくためのもの。

### ファイルの種類
ファイルにはテキストファイルとバイナリファイルの2種類ある。

#### テキストファイル
テキストファイルは単に文字列が書かれたファイル。

#### バイナリファイル
バイナリファイルはテキストファイル以外の画像や音声、実行ファイルなど。バイナリファイルの中身はコンピュータが読むものなので人間が読むのには適していない、

### 関連するコマンド
ファイルの操作に関連する主なコマンド。
#### cat
concatenateの略で、ファイルの中身を表示するコマンド。

```
// ファイルの中身を表示する。
cat [ファイル名]
```

#### less
ファイルの中身をスクロール表示するコマンド。`cat`コマンドだとファイルの中身の記述が多いと画面に入りきらなくなるが、`less`コマンドを使うとスクロールで表示できる。

```
// ファイルの中身をスクロールで表示する。
less [ファイル名]
```

スクロールの操作 ※macの場合
<table>
    <thead>
        <tr>
            <th>コマンド</th><th>操作</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>ctrl + f</td><td>一画面下にスクロール</td>
        </tr>
        <tr>
            <td>ctrl + b</td><td>一画面上にスクロール</td>
        </tr>
        <tr>
            <td>ctrl + j</td><td>一行下にスクロール</td>
        </tr>
        <tr>
            <td>ctrl + k</td><td>一行上にスクロール</td>
        </tr>
        <tr>
            <td>q</td><td>lessコマンドを終了</td>
        </tr>
        <tr>
            <td>/文字列</td><td>下方向に向かって検索</td>
        </tr>
        <tr>
            <td>?文字列</td><td>上方向に向かって検索</td>
        </tr>
        <tr>
            <td>n</td><td>次の検索結果に移動</td>
        </tr>
        <tr>
            <td>N</td><td>前の検索結果に移動</td>
        </tr>
    </tbody>
</table>


#### touch
空のファイルを作成するコマンド。

作成したいファイルと同じ名前のファイルが既に存在していても上書きしない。

```
// ファイルを作成する
touch [ファイル名]

// 複数のファイルを作成する（ファイル名の間にスペースを入力するとエラーになるので注意）
touch {file1,file2,file3}

// ディレクトリの中にファイルを作成する
touch dir/file

// ディレクトリの中に複数のファイルを作成する
touch dir/{file1,file2,file3}
```

#### rm
removeの略でファイル・ディレクトリを削除するコマンド。

オプションをつけずにディレクトリを削除しようとすると`is a directory`というエラーが表示される。

`rm`コマンドで削除されたものはゴミ箱に行くのではなく完全に削除されるので注意。

```
// ファイルを削除する
rm [ファイル名]

// ディレクトリを対象に、ディレクトリの中のファイルやディレクトリもまとめて削除する
rm -r [ディレクトリ名]

// 削除前に確認を行う
rm -i [ファイル名]

// 警告文を表示せずに強制的に削除する
rm -f [ファイル名]
```

#### mv
moveの略で、ファイルを移動するまたはファイル名を変更するコマンド。

```
// ディレクトリの場合
mv [移動元] [移動先]

// ファイルの場合
mv [元のファイル名] [新しいファイル名]
```

#### cp
copyの略で、ファイルやディレクトリをコピーするコマンド。

コピー先にディレクトリを指定すると、コピー元のファイルと同じ名前でコピー先のディレクトリの中にコピーできる。

コピー元にディレクトリを指定すると`[ディレクトリ名] is a directory (not copied).`というエラーが表示されるので注意。（オプションでディレクトリもコピーできる）

```
cp [コピー元] [コピー先]

// ディレクトリをコピーしたい場合
cp -r [コピー元のディレクトリ] [新しいディレクトリ]
```

#### ln
linkの略で、リンクを貼るコマンド。

リンクとは、ファイルに別の名前をつけて複製したように見せるもの。リンクを張ることで長いパス名を省略したり、
リンクにはハードリンクと、シンボリックリンクの2種類ある。

##### ハードリンク
ハードリンクとは1つのファイルに複数の名前をつける機能。元のファイルを削除しても消えず、全てのハードリンクがなくなった時に削除される。

```
// ハードリンクを張る
ln [リンク元ファイル名] [リンク名]
```

##### シンボリックリンク
シンボリックリンクとはリンク先のパス名が書かれた特殊ファイル。リンク先にはフォルダも指定できる。元のファイルが移動したり削除されると参照できなくなるのでシンボリックリンクは使えない。

ハードリンクよりシンボリックリンクの方がよく使う。

```
// シンボリックリンクを張る
ln -s [リンク元ファイル名] [リンク名]
```

#### find
ファイルの場所を検索するコマンド。

```
// 基本の書式
find [検索開始ディレクトリ] [検索条件] [アクション]
```



## 標準入出力
標準入出力とは、プログラムが何も指定されていない場合に利用するデータの標準的な入出力のことで、標準入力・標準出力・標準エラー出力の3つを合わせたものである。

入力とはコンピュータにデータを受け渡すことで、出力とはコマンドやプログラムの実行結果を外に向かって出すこと。入力先と出力先に何も指定しない場合入力はキーボード、出力はディスプレイとなる。

標準エラー出力はプログラムのエラーを表示する出力で、標準出力同様に出力先はディスプレイとなる。

標準入出力を理解することで、コマンドの入出力先を変更し複雑な処理を実行できるようになる。

### リダイレクト
リダイレクトとは入出力先を変更すること。入力と出力で異なる。

#### 入力のリダイレクト
`<`を使うことで、キーボードの代わりにファイルから入力する。

```
// fileの中身をcatコマンドに渡して実行する
cat < file
```

#### 出力のリダイレクト
`>`を使うことで、コマンドの実行結果を画面ではなくファイルに出力する。

ファイルに出力することで、コマンドの結果を保存して後から見ることができる。

```
// lsコマンドの実行結果をfileに保存する（この場合だとファイルが上書きされるので注意）
ls > file

// ファイルに追記する
ls >> file
```

#### エラー出力のリダイレクト
`2>`を使うことで、エラー結果を画面ではなくファイルに出力する。`2`というのはOSが標準入出力を識別するための数値で、`0`は標準入力、`1`は標準出力、`2`が標準エラー出力となっている。

### パイプライン
パイプラインとは、`|`という記号を使ってコマンドの標準出力をつなげること。複数のコマンドを繋げることもできる。

```
// lsコマンドの結果をlessに渡してスクロール表示できる。
ls /bin | less
```

grepコマンドを使うとファイルの中からデータを検索できる。
```
grep [検索条件] [指定ファイル]

// パイプを使うことで標準入力から入ったデータに対し検索できる。
ls /bin | grep 

```


## ユーザー管理
Linuxではユーザーアカウントを作ってログインすることが必要。また複数のユーザーの権限をまとめるためにグループを作ることもできる。

ユーザーやグループの作成などはシステムの管理ユーザーが行う。

### ユーザーを作成する
ユーザーを作成するには`useradd`コマンドを使う。

/etc/passwdファイルに作成したユーザーの情報が定義される。このファイルは直接編集するべきではない。

```
useradd [ユーザー名]
```

ユーザーが作成されたかどうかは/homeディレクトリを見ることで確認できる。

### ユーザーアカウントを変更する
ユーザーアカウントを変更するには`usermod`コマンドを使う。

```
usermod [ユーザー名]
```

### ユーザーを削除する
ユーザーを削除するには`userdel`コマンドを使う。

```
userdel [ユーザー名]
```

### グループを作成する
グループを作成するには`groupadd`コマンドを使う。

/etc/groupファイルに作成したグループの情報が定義される。このファイルは直接編集するべきではない。

```
groupadd [グループ名]
```


### グループアカウントを変更する
グループアカウントを変更するには`groupmod`コマンドを使う。

```
groupmod [グループ名]

// 既存のグループ名を変更する
groupmod -n [新しいグループ名] [既存のグループ名]

// グループIDを変更する
groupmod -g [id] [グループ名]
```

### グループを削除する
グループを削除するには`groupdel`コマンドを使う。

```
groupdel [グループ名]
```

### パスワードを設定する
パスワードを設定するには`passwd`コマンドを使う。

設定したパスワードは/etc/shadowファイルに保存される。このファイルは直接編集するべきではない。

```
passwd [ユーザー名]
```


### rootユーザー
rootユーザーとは、システムの管理者で、利用に制限がない特別なユーザー。

rootユーザーで直接ログインして作業するとrootユーザーの履歴しか残らないので、誰がrootユーザーでどんな作業をしたのかわかるように一般ユーザーでログインしてからrootユーザーの権限を取得することが望ましい。


コマンドの前に`sudo`をつけるとrootユーザーとして実行できる。
`sudo`はswitch user and doの略。
```
// 例
sudo yum update
```

## パーミッション
パーミッションとはディレクトリやファイルを操作するときの誰がどんな操作をできるのかという権限のこと。

Linuxでは複数のユーザーがログインして使うので、勝手にファイルを編集されたり、システムが変更されないように権限を定める必要がある。

### 所有者と所有グループ
全てのファイルには所有者と所有グループが設定されている。

所有者と所有グループは`ls -la`コマンドで確認できる。

### パーミッションの見方
パーミッションは`ls -l`コマンドで確認でき、以下のように表示される。
```
-rwxr-xr-x
```

1文字目がファイルタイプで、1文字目以降は3文字ずつセットで権限を表しており、所有者→所有グループ→その他のユーザーの順番になっている。

分解すると
- -　→ ファイルタイプ
- rwx → 所有者の権限
- r-x → 所有グループの権限
- r-x → その他のユーザーの権限


<br>
ファイルタイプの記号
<table>
    <thead>
        <tr>
            <th>記号</th>
            <th>ファイルタイプ</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>-</td>
            <td>ファイル</td>
        </tr>
        <tr>
            <td>d</td>
            <td>ディレクトリ</td>
        </tr>
        <tr>
            <td>l</td>
            <td>シンボリックリンク</td>
        </tr>
    </tbody>
</table>

<br>
パーミッションの記号
<table>
    <thead>
        <tr>
            <th>記号</th>
            <th>権限の種類</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>r</td>
            <td>read （読み取り）</td>
        </tr>
        <tr>
            <td>w</td>
            <td>write （書き込み）</td>
        </tr>
        <tr>
            <td>x</td>
            <td>execute （実行）</td>
        </tr>
        <tr>
            <td>-</td>
            <td>権限なし</td>
        </tr>
    </tbody>
</table>

### パーミッションを変更する
パーミッションを変更するときは`chmod`コマンドを使う。
`chmod`はchange modeの略。

```
chmod [誰に対して] [何をするか] [権限の記号] [ファイル名]
```

誰に対しては`u`が所有者、`g`がグループ、`o`がその他のユーザー、`a`が全ユーザーを表す。

何をするかは、`+`が権限の追加、`-`が権限の削除、`=`が権限の設定を表す。

```
// testファイルに対して所有者に読み取り権限を追加する
chmod u+r test

// testファイルに対してグループの書き込み権限を削除する
chmod g-w test
```

<br>
以下の数値を使うこともできる。与えたい権限の数値を足して扱う。
<table>
    <thead>
        <tr>
            <th>権限</th>
            <th>数値</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>r</td>
            <td>4</td>
        </tr>
        <tr>
            <td>w</td>
            <td>2</td>
        </tr>
        <tr>
            <td>x</td>
            <td>1</td>
        </tr>
    </tbody>
</table>

<br>

```
// 7が所有者の権限、6がグループの権限、5がその他のユーザーの権限を表している
chmod 765 test
```






## プロセス・ジョブ
プロセスとジョブを理解することでシステム管理・開発で起こる問題の解決に役立てることができる。

### プロセス
プロセスとはメモリ上で実行中のプログラムのこと。

コマンドを実行するたびにプロセスが作られ、プロセスごとにIDが割り当てられる。

プロセスはファイルと同じように実行ユーザーが設定されていて、他のユーザーのプロセスを操作できないようになっている。

プロセスを表示するには`ps`コマンドを実行する。
`ps`はprocess statusの略。

```
// プロセスを表示する
ps

// 全ユーザーのプロセスを詳細情報を合わせて表示する（aが全てのユーザーのプロセス、uが詳細情報、xがpsコマンドを実行したユーザーのすべてのプロセスを表す）
ps aux
```


### ジョブ
ジョブとは、まとめて実行されるプロセスの集まりのことで、シェルごとに管理される。

シェルでコマンドを実行する時の一行がジョブとなる。

ジョブはバックグラウンドでプログラムを実行したいときに必要となる。

`jobs`コマンドを使うことで、現在のジョブの一覧を表示できる。
```
// ジョブID、実行状況、実行コマンドを表示する
jobs
```

#### バックグラウンド
バックグラウンドとは、シェルの画面外でコマンドを実行すること。

時間がかかる処理をバックグラウンドで実行することで、コマンドの終了を待たなくてよくなる。

ジョブをバックグラウンドにするには`bg`コマンドを使う。`bg`はbackgroundの略。

```
bg %[ジョブID]
```

コマンドの後ろに`&`をつけることで、直接バックグラウンドで実行できる。
```
ls &
```

#### フォアグラウンド
フォアグラウンドとは、シェルの画面内でコマンドを実行すること。

対話的に操作したいときにフォアグラウンドにする。デフォルトはフォアグラウンドの状態。

ジョブをフォアグラウンドにするには`fg`コマンドを使う。`fg`はfoergroundの略。
```
fg %[ジョブID]
```


## パッケージ管理
Linuxで何らかの機能を追加したいときにパッケージを使うことができる。パッケージとは機能を構成するプログラムの集まり。

パッケージをインストールしたり、削除したりするときにはパッケージマネージャが使われる。

パッケージマネージャとはその名の通りパッケージを管理するツール。

### 依存関係

パッケージマネージャによってパッケージの依存関係を解決することができる。依存関係とは、パッケージを使うために必要になるパッケージの関係のこと。

例えばAのパッケージを使うためにはBとCのパッケージが必要だとする。パッケージマネージャを使わない場合は必要となるA、B、C、全てのパッケージを手作業でインストールしなければならないが、パッケージマネージャを使うとAのパッケージをインストールするだけでBとCのパッケージもインストールしてくれる。

### パッケージ管理システムの種類
Redhat系には`yum`、Debian系には`apt`というそれぞれのディストリビューションでパッケージマネージャがある。

ここでは`yum`を前提とする。

### パッケージをインストールする
パッケージをインストールするには`yum install`を使う。`sudo`をつけて管理ユーザーで実行しないとエラーになる。

```
sudo yum install [パッケージ名]
```

### パッケージを削除する
パッケージを削除するには`yum remove`を使う。

```
sudo yum remove [パッケージ名]
```

### パッケージをアップデートする
パッケージをアップデートするには`yum update`を使う。

```
// 全てのパッケージをアップデート
sudo yum update

// 特定のパッケージをアップデート
sudo yum update [パッケージ名]
```

### インストールしたパッケージを確認する
インストールしたパッケージを確認したいときは`yum list installed`を使う、

```
yum list installed
```


## まとめ
- Linuxとはアプリの土台となるサーバーによく使われるOS
- Linuxを操作するにはシェルでコマンドを入力する
- コマンドの実体はプログラムが書かれた実行ファイルである
- Linuxを理解するためにディレクトリ構造を理解することが重要
- 標準入出力によってコマンドの実行結果を他のコマンドに渡すことができる
- Linuxは複数のユーザーで利用し、ユーザーの管理は管理者ユーザーが行う
- ファイルやディレクトリには誰がどんな操作をできるかという権限がある



## 参考
https://www.udemy.com/course/unscared_linux/
https://kitsune.blog/engineer/linux