Linux の基礎まとめ 〜 備忘録 〜

# はじめに

Webエンジニアとして勤務することになったため、Linuxの基礎についてまとめておきます。
インフラメインではないのと、業務に入ってから概要をざっと見返せるようにすることが目的なので、
プログラミングする上で比較的良く使うコマンドなどが多めです。

# シェルの操作 〜 Linuxの操作を高速に 〜

## カーソルの移動 

| コマンド | 意味 |
|:-:|:-:|
| Ctrl + b  | 1文字戻る  |
| Ctrl + f  | 1文字進む |
| Ctrl + a  | 行頭へ移動する  |
| Ctrl + e |  行末へ移動する |

## 削除のコマンド

| コマンド | 内容 |
|:-:|:-:|
| Backspaceキー / Ctrl + h  | カーソル位置の後方に1文字を削除する  |
| Ctrl + w  | 後方にスペース区切りで１単語ぶんを削除する |

## カットとペースト

| コマンド | 内容 |
|:-:|:-:|
| Ctrl + k  | カーソル位置から行末までを削除する  |
| Ctrl + u  | カーソル位置から行頭まで削除する  |
| Ctrl + y  | 最後に削除した内容を挿入する  |

## ターミナルが反応しなくなった時

| コマンド | 内容 |
|:-:|:-:|
| Ctrl + s  |  画面表示をロックする |
| Ctrl + q  |  画面表示のロックを解除する |
| Ctrl + c  | 実行中のコマンドを強制終了する |

## ターミナルをきれいに

| コマンド | 内容 |
|:-:|:-:|
| Ctrl + l  |  ターミナルの画面を消去する |

## コマンド履歴をチェック

| コマンド | 内容 |
|:-:|:-:|
| Ctrl + p / ↑  | 1つ前のコマンド履歴に移動  |
| Ctrl + n / ↓  | 次のコマンド履歴へ移動  |
| Ctrl + r  | 履歴を遡って検索する  |
| Ctrl + q  | 検索結果を破棄して、プロンプトに戻る  |

## よく使うコマンドの紹介

#### pwd

現在のディレクトリのパスを表示するために使用される。

```zsh
$ pwd
/home/user/Documents
```

#### cd
ディレクトリ移動に使用されるコマンド
 
```zsh
# cd パス
$ cd /home/user/Documents
```
#### ls

指定されたディレクトリ内のファイルとディレクトリのリストを表示するために使用されます。

```zsh
$ ls
dev test.txt
```

lsコマンドでよく利用するオプション

```zsh
# -a：隠しファイルを含めて全てのファイルを表示する。
$ ls -a
# -l：詳細情報を表示する。
$ ls -l
# 同時に指定する
$ ls -la
```

#### mkdir

新しいディレクトリを作成するために使用されるコマンド


```zsh
$ mkdir directoryName
```

#### touch

新しいファイルを作成するために使用されるコマンド

```zsh
$ touch newFileName.txt
```

#### rm

指定されたファイルを削除するために使用されるコマンド

```zsh
$ rm file.txt
```

rmコマンドでよく利用するオプション

```zsh
# 削除の確認を行う。 削除してはダメなファイルが存在する箇所で実行する場合は付けたほうがbetter
$ rm -i file.txt
# ディレクトリを削除する
$ rm -r /dir
```

#### cat

指定したファイルの内容を表示するコマンド。容量の大きいファイルで実行すると地獄なので注意。

```zsh
$ cat file.txt
```

#### less

ファイルの内容をページ単位で表示するコマンド。大きなファイルを扱うときに便利。
ファイルの中身は space キー を押すことで 1ページ送りで実行することができる。

```zsh
less bigfile.txt
```

#### cp

ファイルまたはディレクトリをコピーするコマンド。

```zsh
$ cp file.txt newfile.txt
# -r: ディレクトリをコピーする際に使用する。
$ cp -r directory/ newdirectory/
# -i: 上書きする前に確認を求める。
$ cp -i file1.txt file2.txt
```

#### mv

ファイルまたはディレクトリを移動する、または名前を変更するコマンド。

```zsh
$ mv file.txt directory/
$ mv file.txt newname.txt

# -i: 移動先に同名のファイルが存在する場合に確認を求める。
mv -i file1.txt dir1/
```

#### man

コマンドのマニュアルを表示するコマンド。

```zsh
$ man ls
$ man cp
```

#### which

指定されたコマンドがどのディレクトリにインストールされているかを調べるためのコマンド

```zsh
$ which ruby
$ which ls
```

#### chmod

chmodは、ファイルやディレクトリのアクセス権限を変更するためのコマンド

`chmod [オプション] モード ファイル名`

モードには、r(read)、w(write)、x(execute)の3種類があり、それぞれを表す数字が割り当てられています。


```zsh
# password.txtファイルの所有者には読み書き実行権限、グループとその他のユーザーには読み取りと実行の権限が与えられます。
$ chmod 755 password.txt
# オプションには、-R(再帰的に変更)、-v(変更したファイル名を表示)、-f(エラーが発生しても無視する)などがあります。
```

#### chown

ファイルやディレクトリの所有者を変更するためのコマンドです。

chownの基本的な使い方は、`chown [オプション] 新しい所有者名 ファイル名`

```zsh
# ファイルの所有者がuserに変更
$ chown user password.txt
```

#### sudo

superuser(管理者)としてコマンドを実行するためのコマンドです。

```zsh
# 管理者として、Ubuntuのパッケージ情報を更新する
$ sudo apt-get update
```

#### ps

実行中のプロセス情報を表示するコマンド

```zsh
# 実行中の全てのプロセスを表示します。
$ ps aux

# a：全てのプロセスを表示する。
# u：詳細情報を表示する。
# x：制御端末を持たないプロセスを表示する。
```

ps aux を実行すると以下の項目が表示されますが、意味は以下の通り。

| 項目名 | 説明 |
|:-:|:-:|
| USER  | プロセスを起動したユーザー名  |
| PID  | プロセスのID  |
| %CPU  | プロセスが使用しているCPU使用率  |
| %MEM  | プロセスが使用しているメモリ使用率  |
| VSZ  | プロセスの仮想メモリ使用量 (キロバイト単位)  |
| RSS  | プロセスの物理メモリ使用量 (キロバイト単位)  |
| TT  | ターミナルの識別子 (tty/pts)  |
| STAT | プロセスの状態を示す状態フラグ  |
| STARTED  | プロセスが開始された日時 |
| TIME | プロセスが実行されたCPU時間 (分単位) |
| COMMAND | プロセスを実行しているコマンドの名前またはパス |

#### kill

指定したプロセスを終了させるコマンドです。
基本的には`kill [オプション] [プロセスID]` のように定義して実行する

```zsh
# プロセスIDが1234 のプロセスを強制終了させる
$ kill -9 1234
```

#### head

headは、ファイルの先頭から指定された行数のみを出力するコマンドです。
指定されたファイルの先頭から、デフォルトでは最初の10行を出力します。


```zsh
# -nオプションを使用して、出力する行数を変更することができます。
$ head -n 20 file.txt
# ファイルの最初の20行を出力します。
```

#### tail

tailは、ファイルの末尾から指定された行数のみを出力するコマンドです。
指定されたファイルの末尾から、デフォルトでは最後の10行を出力します。

```zsh
# ファイルの最後の20行を出力します。
$ tail -n 20 file.txt
```

head と tail コマンドは、大きなファイルの先頭または末尾の一部だけを表示するために便利であり、
ログファイルや他の大きなテキストファイルを処理する場合に特に役立ちます。

#### uniq

ファイルやコマンドの標準入力から連続した重複した行を検出し、それらを単一の行にまとめるために使用されます。

以下は、uniq コマンドの使い方の例です。
```zsh
$ cat file.txt
apple
banana
banana
cherry
cherry
cherry

# uniq コマンドは、連続する重複した行を単一の行にまとめるため、通常はソートされたファイルや
# コマンド出力と組み合わせて使用されます。例えば、以下のようにします。

$ sort file.txt | uniq
apple
banana
cherry
```

#### grep

ファイル内の指定したパターン（文字列）を検索するためのコマンドです。

`grep [オプション] パターン ファイル名` のように指定して使用します。

パターンでは、検索したい文字列や正規表現を指定します。

ファイル名は検索対象のファイル名を指定します。
複数のファイルを検索する場合は、複数のファイル名を指定するかワイルドカードを使用します。

grepのオプションで代表的なものとして、「-i」（大文字と小文字を区別しない）、「-v」（指定したパターン以外を表示）、「-n」（行番号を表示）などがあります。

```zsh
# 特定の文字列を含む行を表示する。
$ grep "apple" fruits.txt
# 複数のファイルから特定の文字列を含む行を表示する。
$ grep "apple" fruits.txt vegetables.txt
# 大文字と小文字を区別せずに特定の文字列を含む行を表示する。
$ grep -i "APPLE" fruits.txt
# 正規表現を使用して特定の文字列を含む行を表示する。
$ grep "app*" fruits.txt
# 特定の文字列を含まない行を表示する。
$ grep -v "apple" fruits.txt
# 行番号を表示して特定の文字列を含む行を表示する。
$ grep -n "apple" fruits.txt
# 特定のディレクトリ以下のファイルから特定の文字列を含む行を表示する。
$ grep "apple" /path/to/directory/*
```

#### tr

テキストをトランスレートするために使用されます。つまり、文字の置換や削除を行うことができます。

trコマンドは、2つの文字セットを指定し、入力を1つの文字セットからもう一つの文字セットに変換することができます。

```zsh
$ echo "hello world" | tr "l" "L"
heLLo worLd
```

この例では、echoコマンドを使用して"hello world"という文字列を出力し、|パイプを使用して、trコマンドに渡します。
trコマンドは"l"を"L"に置換するために使用され、出力される文字列は"heLLo worLd"になります。

#### sed

ストリームエディタとして知られており、テキスト処理に使用されます。行の追加、削除、検索、置換など、さまざまな操作を実行できます。
sedコマンドは、スクリプトファイルまたはコマンドラインから直接実行できます。

```zsh
$ echo "Hello World" | sed 's/Hello/Goodbye/'
Goodbye World
```

この例では、echoコマンドを使用して、"Hello World"という文字列を出力し、|パイプを使用して、sedコマンドに渡します。
sedコマンドは、s/Hello/Goodbye/スクリプトを使用して、"Hello"を"Goodbye"に置換し、
出力される文字列は"Goodbye World"になります。

#### awk

ファイルを処理してパターンに一致する行を見つけ、行のフィールドを指定した方法で処理するために使用されます。
awkコマンドは、スクリプトファイルまたはコマンドラインから直接実行できます。

```zsh
$ awk '{print $2}' file.txt
```

この例では、awkコマンドを使用して、file.txtファイル内のすべての行の2番目のフィールドを出力しています。

# Linux のディレクトリ構造

一般的なディレクトリ構造と各ディレクトリの構成

```markdown
/ : ファイルシステムの最上位に位置するディレクトリ。通常、ルートファイルシステムと呼ばれます。
├── bin : システムの基本的なコマンドが格納されているディレクトリ。ls、cp、mv、rmなどよく使用されるコマンドが含まれる。
├── boot : Linuxカーネルとブートローダーのファイルが格納されているディレクトリです。
├── dev : デバイスファイルが格納されているディレクトリ。Linuxは、すべてのデバイスをファイルとして扱います。
├── etc : システムの設定ファイルが格納されるディレクトリ。
├── home : ユーザーホームディレクトリが格納されるディレクトリです。
|          各ユーザーには、/home/ユーザー名のようなサブディレクトリが割り当てられる。
├── lib : 共有ライブラリが格納されているディレクトリです。ここには、プログラムが使用する共有ライブラリが含まれます。
├── media : 取り外し可能なメディア（CD、DVD、USBドライブなど）をマウントするためのディレクトリです。
├── mnt : マウントポイントとして使用されるディレクトリ。ファイルシステムが一時的にマウントされることがある。
├── opt : オプションのアプリケーションが格納されるディレクトリ。
|         ここには、サードパーティーのアプリケーションがインストールされることがある。
├── proc : プロセス情報を提供するための仮想ファイルシステム。実際のファイルシステムではなく、
|          カーネルメモリ上にマウントされているため、ファイルシステムの情報を直接的に読み書きすることはできない
├── root : ルートユーザーのホームディレクトリが格納されているファイルシステム。
|          ルートユーザーはシステム上で最高の権限を持っており、システム全体を管理できます。
├── sys : カーネルとデバイスの情報を提供する仮想ファイルシステム。
|          ここには、デバイスやバス、プロセス、CPU、メモリ、ネットワークなど、システムに関する情報が含まれます。 
├── sbin :
├── var : 変化するデータが格納されるファイルシステム。ログファイル、プログラムによって生成されたデータなどが含まれます。
|         また、Webサーバーやデータベースサーバーのデータファイルも格納されることがある。
├── tmp : 一時的なファイルを保存するためのディレクトリ。
|         Linuxシステムでは、多くのアプリケーションが/tmpディレクトリを使用して、一時的なファイルを作成します。
|         /tmpディレクトリに作成されたファイルは、システムが再起動されると削除される。
└── usr : ほとんどのユーザー向けのアプリケーションやファイルが格納されているファイルシステム。
          ここには、ユーティリティ、アプリケーション、ライブラリ、マニュアルなどが含まれます。
```

## パス p110 / p116

パスとは、ファイルやディレクトリの場所を表すために使用される文字列のことです。
Linuxにおいては、以下の2種類のパスが存在する

### 絶対パス（Absolute Path）
ファイルやディレクトリを、ルートディレクトリからの完全なパスで表します。
すべての絶対パスは、ルートディレクトリで始まり、ファイルまたはディレクトリの名前を含みます。
たとえば、`/home/user/file.txt`は、ルートディレクトリ（`/`）から始まる完全なパスで、
`file.txt`というファイルが`/home/user/ディレクトリ`にあることを示しています。

### 相対パス（Relative Path）
ファイルやディレクトリを、現在の作業ディレクトリからの相対的な位置で表します。

たとえば、`file.txt`というファイルが現在の作業ディレクトリである`/home/user/ディレクトリ`にある場合、
`file.txt`という相対パスは`/home/user/file.txt`という絶対パスと同じ。

一方、`../file.txt`という相対パスは、現在の作業ディレクトリの1つ上のディレクトリにある`file.txt`というファイルを表します。

絶対パスと相対パスは、ファイルやディレクトリを指定する場合に使用されます。
絶対パスは、システム上の任意の場所からファイルを参照することができますが、長くて煩雑な場合があります。

相対パスは、現在の作業ディレクトリからの相対的な位置で指定するので、短くて簡潔な場合があります。
ただし、作業ディレクトリが変更された場合には、相対パスも変更する必要があります。

## パーミッション

Linuxにおいては、ファイルやディレクトリに対してアクセス権限を設定する仕組みのことを指す。

一般的に、パーミッションは所有者、グループ、その他のユーザーに対して、読み取り、書き込み、実行の3つのアクセス権限を設定する。

数値、または、記号を用いてパーミッションを指定することが可能です。

数値表現を用いる場合は、4, 2, 1 の数字を覚えておくと良く、  
4(読み込み権限), 2（書き込み権限）, 1（実行権限）という意味になります。

```zsh
# chmod 所有者:グループ:その他のユーザー
# user.txtへ所有者のみに読み込み権限だけ設定
chmod 400 user.txt
# user.txtへ所有者へ全権限、グループとそのほかのユーザーへ読み込みと実行権限を付与
chmod 755 user.txt
```

記号表現でパーミッションを指定する場合は以下のように指定できます。
r(read)、w(write)、x(execute) の文字列を組み合わせて表現されます。
u、g、o、aという文字を使用して、それぞれ所有者、グループ、他ユーザー、全てのユーザーを表現することもできます。

```zsh
# user.txtへ所有者のみに読み込み権限だけ設定
chmod u+r user.txt    # ファイル.txtに対して所有者に読み書き実行、グループと他ユーザーに読み実行を許可する
# user.txtへ所有者へ全権限、グループとそのほかのユーザーへ読み込みと実行権限を付与
chmod u+rwx go+rx
```

## シェル変数

シェル変数（Shell Variables）は、シェルプログラム内で定義された変数のことでローカルスコープを持つ。
シェル変数はシェルプログラム内でのみアクセス可能であり、他のプログラムからは見えない。

一般的に、スクリプト内の一時的なデータを保存するために使用されます。
シェル変数は、$記号を使用して参照されます。

```zsh
VAR="Hello, World"
echo $VAR 
# Hello World が出力される
```

## 環境変数

環境変数（Environment Variables）は、システム全体で定義された変数で、グローバルスコープを持ちます。

つまり、環境変数は、シェルプログラムだけでなく、システム上のすべてのプログラムでアクセス可能です。

通常、システム設定やプロセス間通信などの目的で使用されます。

環境変数は、exportコマンドを使用して設定されます。

```zsh
# 現在のPATHに/usr/local/binを追加
export PATH=$PATH:/usr/local/bin
# 環境変数PATHの値を表示
echo $PATH
```

Webアプリケーションの開発においては、DBの接続情報など流出してはいけない情報を環境変数に格納することが一般的です。

## 標準入力・標準出力・標準エラー出力

標準入力、標準出力、標準エラー出力は、Linuxにおいてプロセスがデータの入出力を行う際に使用される3つのストリームのこと

### 標準入力（Standard Input）
キーボードやファイルなどからデータを読み込むストリームです。Linuxのプログラムは、標準入力からの入力を受け取って処理を行うことができます。
標準入力は、通常、キーボードからの入力を受け付けることが多いですが、ファイルやパイプからの入力を受け取ることもできます。
標準入力のストリームは、通常、ファイルディスクリプタ番号0で表されます。

### 標準出力（Standard Output）
プログラムが出力するデータを表示するストリームです。Linuxのプログラムは、標準出力に対して出力を書き込むことができます。
標準出力は、通常、ターミナル画面に表示されますが、リダイレクトやパイプを使用してファイルに書き込むこともできます。
標準出力のストリームは、通常、ファイルディスクリプタ番号1で表されます。

### 標準エラー出力（Standard Error）
プログラムが出力するエラーメッセージなどの情報を表示するストリームです。標準エラー出力は、通常、標準出力とは別のストリームとして扱われます。
これは、標準出力と標準エラー出力を分けることで、プログラムの出力とエラーメッセージを区別しやすくするためです。
標準エラー出力のストリームは、通常、ファイルディスクリプタ番号2で表されます。


```zsh
ls -l /etc/passwd /etc/shadow /etc/group 2> error.log
```

このコマンドは、`/etc` ディレクトリ内の `passwd、shadow、group` の3つのファイルについて、詳細な情報を表示する ls コマンドです。

そして、エラーが発生した場合は `error.log` ファイルにエラーメッセージを出力します。

このコマンドでは、標準出力（通常のコマンドの出力）はターミナルに表示されます。
つまり、ls コマンドの実行結果が直接ターミナル上に表示されます。

一方、標準エラー出力はリダイレクトされて `error.log` ファイルに書き込まれます。
これは、もし `ls` コマンドが `passwd、shadow、group` ファイルのうちのいずれかにアクセスできなかった場合に、
エラーメッセージが `error.log` ファイルに書き込まれることを意味します。

標準入力については、このコマンドでは使用されていません。
しかし、標準入力は通常、キーボードからのユーザー入力など、プログラムにデータを提供するために使用されます。

# まとめ

コマンドを全て暗記するのは多すぎてとても無理ですが、、、、、この記事の内容くらいは使う場面で思い出せるようにしておきたい。
業務で追加で学べたことがあったり、時間ができたら適宜記事の内容は追加していきます。