【Linux】初学者が知っておきたい、アレとか、コレとか……

## はじめに
この記事は、Linuxを初めて学ぶ過去の自分に向けてLinuxの学習を続けられることを目的として書きました。

Linuxは広くて深い世界なので学習コストが高く、途中で挫折してしまったり、勉強してもよくわからないままでいることも少なくありません。

ですので、記事の内容はLinuxの学習で「ここは大事だな」と思うところを一つずつ拾い上げて、自分の言葉で説明したものとなっています。

大まかにですが、``OS → Linuxの概要 → Linuxのディレクトリ →　Linuxのコマンドとオプション`` という流れになっています。

読み終えた後に「Linuxってこんな感じなんだ」と思ってもらえたら嬉しいです。

### 環境情報
- macOS Ventura 13.4.1
- Intel core i5
- Darwin Kernel Version 22.5.0


## Linuxを学ぶ前にOSを知ろう
Linuxを学ぶ前にOSの概念をを知っておくことでLinuxの学習がしやすくなります。

### OSとは？
OSは**O**perating **S**ystemの略で、コンピューターを管理しているソフトウェアのことです。
そんなOSは私たちの身近に存在しています。

| デバイス | OSの種類 |
| :---: | :--- |
| PC | Windows、macOS、UNIX、**Linux**など |
| スマートフォン | iOS、Androidなど |

OSはPCだけでなくスマートフォンにもインストールされていて、近年ではゲーム機、冷蔵庫、エアコン、自動車などにもOSが組み込まれています。

### OSの機能
OSが具体的にどのような働きをするのか確認してみましょう。

| OSの機能 | 説明 |
| :--- | :--- |
| ユーザー管理 | コンピュータを使う人々（ユーザー）のアカウントを作成・管理し、アクセス権限やパスワードを設定・管理します。 |
| ファイル管理 | ファイルやフォルダを整理・保存し、データを読み書きします。ファイルを開いたり、削除したりすることができます。 |
| 入出力管理 | キーボードやマウスからの入力を受け取り、画面やプリンターに出力します。 |
| タスク管理 | 複数のプログラムが同時に動作する場合、それらのプログラムを切り替えながら処理します。 |
| メモリ管理 | プログラムが必要なメモリ領域を確保したり解放したりして、効率的にプログラムを実行します。 |

他にもいろいろな機能があるのですが「OSってこんなことができるんだ」とざっくりとした把握で大丈夫です。

### OSの構造
OSの構造は「カーネル」と「シェル」に分けることができます。

#### カーネル(Kernel)
コンピューターの中心で、ハードウェアを制御し、アプリケーションやハードウェアを管理しています。
Kernelは「中核」という意味で、その名のとおりコンピューターの中で重要な役割を担っています。

また、カーネルはデリケートな部分なので我々ユーザーが自由に操作することができません。
そのため、カーネルとユーザーとのやり取りはシェルが行ってくれます。

カーネルとは
- コンピューターの中心で、OSの最も重要な部分
- アプリケーションやハードウェアを管理・制御
- ユーザーは直接扱うことができない

#### シェル(Shell)
シェルはカーネルとユーザーを繋いでくれる役割を担います。
実際にユーザーはシェルを通してカーネルとやり取りを行います。
Shellは「殻、貝殻」という意味で、中核であるカーネルを貝殻であるシェルが包み込んでいるイメージです。

シェルとは
- カーネルとユーザーを繋ぐ役割を担う
- (ユーザーはカーネルに直接やり取りができないので)ユーザーはシェルを通してカーネルとやり取りを行う

![スクリーンショット 2023-08-04 15.14.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599480/8c55b605-375d-0403-f288-b991afd644ef.png "ユーザー、シェル、カーネルの関係")

※ この「カーネル」と「シェル」はLinuxにおいてよく出てくるのでしっかり覚えておきましょう。


## Linuxの概要
1. Linux（リナックス）はWindowsやmacOSなどと同じOSの一つです。

2. 1991年にフィンランドの大学生Linus Torvalds氏によって開発されました。もとはコンピューターの機能の学習のために作り上げた小さなプログラムでしたが、幾つもの拡張機能やソフトウェア、ツールなどを組み合わせて今のLinuxができあがりました。

3. Linuxはオープンソース[^1]なので、ユーザーや開発者はLinuxのソースコード[^2]を自由に見ることができて、必要に応じて改良やカスタマイズを行えます。この自由な性質が、Linuxを世界中の多くのユーザーに愛される理由の一つです。

4. 現在はパソコンだけでなく、スマートフォンや家電などのOSとして利用されています。

5. Webアプリケーションの公開をする時に必要となる「Webサーバー」を設定する際にもLinuxが利用されることも多いです。

[^1]:オープンソース：コンピューターソフトウェアの開発や配布方法の一つで、ソフトウェアのソースコードを公開して誰でも自由に閲覧、使用、改変、再配布ができる仕組みを指します。
[^2]:ソースコード：コンピューターソフトウェアがプログラムされたテキストファイル（設計図のようなもの）のことを指します。


### Linuxのメリット
Linuxのメリットは大きく分けて次の4つです。

#### 1.オープンソース
LinuxはオープンソースのOSであり、無料でソースコードが公開されています。

#### 2. 性能の低いコンピューターでも動かすことができる
例えば10年から20年前のWindowsやmacに今のWindowsやmacOSを導入するとスペックが足りなくて動いてくれません。しかし、Linuxは型が古いコンピューターでも動いてくれます。

#### 3. 業務のための環境を構築・開発するためのソフトウェアが多い
IT企業向けのサーバーを構築・開発するためのソフトウェア、開発するためのソフトウェアがLinuxでは充実しています。

#### 4. カスタマイズ性の高さ
カスタマイズ性とは、Linuxを自分好みに変えることができることを意味します。
例えば、自分の好きな色やデザインにターミナルの見た目を変えたり、自分の使いたいソフトウェアを自由にインストールしたり、更にはコンピューター内部の設定を細かく調節することもできます。

### Linuxのデメリット
Linuxのデメリットは大きく分けて次の3つです。

#### 1. 学習コスト
Linuxは初心者にとって学習コストが高いと感じるかもしれません。コマンドライン操作[^3]や設定ファイルの編集などが必要な場面が多々あります。

#### 2.操作性
Linuxは業務用で使用されるため、WindowsやMacに比べて操作方法が直感的ではありません。

#### 3.サポート面
誰でも無料で入手できるオープンソース故にサポートが充実していないことが挙げられます。

[^3]:コマンドライン操作：コンピューターをキーボードから直接命令して操作する方法です。ターミナルやコマンドプロンプトを使い、コマンドを入力することでファイルの作成や削除、ディレクトリの移動などができます。文字だけで操作するため、シンプルで効率的ですが、正確なコマンドを覚える必要があります。


### ディストリビューション(distribution)
開発当初のLinuxはインストール作業が非常に困難で一部のコンピュータのスキルが高いユーザしか使うことができませんでした。そこで、さまざまな団体やボランティアがLinuxを使う上で必要なプログラムをまとめて簡単な手順で手軽にインストールできるようにしました。

これを「Linuxディストリビューション」または「ディストリビューション」と呼びます。
ディストリビューションは「分配、配給、配布」を意味します。

Linuxの代表的なディストリビューションは次の3つです。

#### Red Hat Enterprise Linux (RHEL)
- RedHat 社が開発した最も有名な商用向けのディストリビューションです。
- 有料のためサポート面で安心感があり、多くの企業で用いられています。
- 有償のLinuxディストリビューションの中で最も有名で実績も多いです。そのため、動作が安定しています。
- 困った時にRedHat社に相談できる商用サポートがあります。

有料でもいいから動作の安定したLinux環境が使いたい、アプリケーション開発からリリースまでを考えている場合におすすめです。

#### Ubuntu(ウブンツ)
- 「誰でも使いやすいOS」をモットーに作られたLinuxディストリビューションです。
- 初心者向けではありますが、性能が劣っているということはありません。
- 「CUI操作」だけでなく「GUI操作」もできます。
- macOSやWindowsに似せた画面にすることができます。
- Ubuntuソフトウェアセンターで豊富なフリーソフトが使えます。

初めてLinuxを使うユーザー、CUI操作が基本だけどいきなりキーボードだけの操作は難しいと感じるユーザー、Linuxのコマンドを覚えるのが大変だと感じるユーザーにおすすめです。

※ CUIとGUIの詳細は後述します。

#### CentOS（セントオーエス）
- Red Hat Enterprise Linux(RHEL)の完全互換を目指した、Linuxディストリビューションの1つです。Red Hat Enterprise Linux(RHEL)の無料版というイメージです。

詳しくみてみると、次のような違いがあります。

|  | Red Hat Enterprise Linux(RHEL) | CentOS |
| :---: | :---: | :---: |
| 費用 | 有料 | 無料 |
| サポート | 商用サポートあり | 商用サポートなし |

※ 上記の3つ以外にも多くのディストリビューションが存在しています。


## CUIとGUI
CUI（**C**haracter-based **U**ser **I**nterface）とGUI（**G**raphical **U**ser **I**nterface）は、コンピュータを使う際の操作方法の違いです。
この2つはLinux特有のものではありませんが、コンピューターを学ぶ上で重要な用語ですので覚えておきましょう。
それぞれの特徴を挙げてみました。

### CUI(Character-based User Interface) - 文字ベースでの操作 -
- 文字を操作する：コンピューターとのやり取りをキーボードで文字を入力して行います。
- コマンドを使う：特定のキーワード（コマンド）を入力することでコンピューターにさまざまな指示を出すことができます。
- テキストベース：画面に表示されるのは文字だけで絵やアイコンはありません。
- 自由度が高い：CUIはコマンドを組み合わせて使うことでさまざまな操作が可能です。
- シンプルで軽量：グラフィックやアニメーションがないため、システムの動作が軽く、高速に動作します。
- プログラミングに使える：文字ベースの操作でプログラムを書くこともでき、コンピューターの制御も細かく行えます。

CUIの操作は初めは難しく感じるかもしれませんが、慣れてくると効率的にコンピューターを使えるようになります。

### GUI(Graphical User Interface) - 絵やアイコンベースでの操作 -
- 画面に絵やアイコンが表示される：コンピュータの操作を、絵やアイコンをクリックすることで行います。
- マウスやタッチパッドで操作：画面上のアイコンやウィンドウをマウスやタッチパッドで操作します。
- ドラッグ＆ドロップ：ファイルやアプリケーションをドラッグして、別の場所にドロップすることで操作を行います。
- 直感的な操作：アイコンやボタンの形状や配置が直感的でわかりやすく、使いやすいです。

GUIは見た目が豊かで操作が直感的なため、初心者でも使いやすいです。マウスやタッチパッドを使って操作することで、コンピュータの機能を簡単に利用できます。


## ファイル・フォルダ・ディレクトリ
Linuxを学ぶにはデータを保管してくれるファイル・フォルダ・ディレクトリの3つの入れ物について知っておかなければなりません。

### ファイル
ファイルは、コンピューターで扱われるデータが保管されている入れ物です。
例えば、音楽のMP3ファイルは音楽が、作成したワードファイルには文章（テキスト）が、データとして保管されています。
実は、PCやスマートフォンで使用しているアプリケーションもファイルからできています。

### フォルダ
ファイルを入れる入れ物です。
一つの場所にたくさんのファイルがあると分かりにくいのでフォルダにファイルを分けて格納します。
例えば、「Picturesフォルダ」には写真ファイルを保存したり、「Documentsフォルダ」には文章ファイルを保存します。

### ディレクトリ
フォルダと同じ意味を持ちます。

### ディレクトリ?それともフォルダ?
ディレクトリとフォルダは、どちらもコンピューターの中でファイルを整理するための入れ物のようなものです。
Linuxではフォルダのことをディレクトリと言います。

ですので、Linuxにおいてデータを保管してくれる入れ物は、ファイルとディレクトリ（フォルダ）の2種類だと認識してください。


## ディレクトリ構造
Linuxの操作はディレクトリを中心に移動したり、編集したり、新しくデータを作ったり……といった作業を行います。

そんなディレクトリがLinuxの中でどのような組み合わせになって全体を形作っているのかを知ることはLinuxを理解するために大切なことです。

ディレクトリ構造の特徴を挙げてみました。

- ディレクトリ（フォルダ）が階層的に組織された形（構造）を指します。
- 階層的に組織された形（構造）を「階層構造」または「ツリー構造（樹形図）」と言います。

「ディレクトリ」という言葉を見掛けたら以下のような図を頭に浮かべてください。

![スクリーンショット 2023-08-04 15.42.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599480/9271853f-e7ba-4e8b-b717-18f68e881da2.png "ディレクトリ構造の一例")


## 特別なディレクトリ
ディレクトリを操作するために覚えてほしい特別なディレクトリが4つあります。
ルートディレクトリ・ホームディレクトリ・カレントディレクトリ・親ディレクトリです。
これらはディレクトリの居場所を把握するために必要なディレクトリです。

### ルートディレクトリ
ディレクトリ階層の最上階層のことです。
ファイルやディレクトリ操作では「 `/`（スラッシュ、ルート）」を使って表します。
ファイルシステムの始まりの場所で、全てのファイルやディレクトリはここから始まります。
「ルート」とも呼ばれ、ルート(root)は「起源、根っこ」を意味します。

### ホームディレクトリ
ユーザーの作業開始位置となるディレクトリです。
Linuxにログイン直後のユーザーは必ずホームディレクトリにいます。
ユーザー毎に異なるホームディレクトリを使うので、ユーザーによってホームディレクトリの場所は異なります。
ファイルやディレクトリ操作では「 `~`（チルダ）」を使って表します。

### カレントディレクトリ
現在いるディレクトリのことをカレントディレクトリと言います。
ファイルやディレクトリ操作では「 `.`（ドット）」を使って表します。
カレント(current)は「現在の、目下の、今の」を意味します。

### 親ディレクトリ
カレントディレクトリの直上にあるディレクトリを親ディレクトリと言います。
親ディレクトリは通常、カレントディレクトリを含む階層の一つ上に位置しています。
ファイルやディレクトリ操作では「 `..`（ドット2つ）」を使って表します。

![スクリーンショット 2023-08-04 16.29.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599480/9e6a2b89-032f-6a96-cd06-e8e1501fe31d.png "ルートディレクトリ、ホームディレクトリ、カレントディレクトリ、親ディレクトリ")


## パス(Path)
ファイルやディレクトリが、どの位置にあるかを教えてくれる文字列のことです。
この文字列は「自分がどこにいるのか?」「自分がどの場所に行きたいのか?」を指し示してくれる大事な情報です。
ファイルやディレクトリへの道筋だとイメージしてください。

そして、ファイルの位置を表した道筋をファイルパス、ディレクトリの位置を表した道筋をディレクトリパスと呼びます。先程紹介したルートディレクトリ、ホームディレクトリ、カレントディレクトリ、親ディレクトリの4つにはそれぞれ「ディレクトリパス」が設定されています。

| 特別なディレクトリ | ディレクトリパス |
| :---: | :--- |
| ルートディレクトリ | 「 `/` 」 (スラッシュ) |
| ホームディレクトリ | 「 `~` 」 (チルダ) |
| カレントディレクトリ | 「 `.` 」 (ドット) |
| 親ディレクトリ（カレントディレクトリの一つ上にある階層） | 「 `..` 」 (ドット2つ) |


## 絶対パスと相対パス
パスはルートディレクトリ( `/` )を起点とした絶対パスとカレントディレクトリ( `.` )を起点とした相対パスの2つの方法で指定することができます。

相対パスでは、1つ上の階層のディレクトリ（親ディレクトリ）は「`..`」（ドット2つ）というパスを使って指定します。

- 以下のディレクトリ構造を例に、「yoshiwo」というディレクトリをカレントディレクトリとした時の絶対パスと相対パスの書き方は下の表のようになります。


```
/
└── abc
     ├── Users
     │      └── yoshiwo
     │              └── study
     │                     └──linux
     └── Work Documents

```
| 各ディレクトリ | 絶対パス | 相対パス |
| :---: | :--- | :--- |
| / | `/` (ルートディレクトリ) ※ ここが起点 | `../../../` |
| abc | `/abc` | `../../` |
| Users | `/abc/Users` | `../` |
| yoshiwo | `/abc/Users/yoshiwo` | `.` (カレントディレクトリ) ※ ここが起点 |
| study | `/abc/Users/yoshiwo/study` | `study` |
| linux | `/abc/Users/yoshiwo/study/linux` | `study/linux` |
| Work Documents | `/Users/yoshiwo/Work Documents` | `../../Work Documents` |

### 絶対パス
- ルートディレクトリを起点として始まるパスのこと
- 目的のファイルやディレクトリまでの完全な道筋を示す方法

### 相対パス
- 現在の位置を起点として始まるパスのこと
- 目的のファイルやディレクトリまで道筋を相対的に示す方法


## Linuxのディレクトリ構造
Linuxのディレクトリ構造はディレクトリの種類が多く、とても分かりにくいですが、知っておくとLinuxを学んだり使ったりした時の習得するスピードが圧倒的に上がりますので、最初にしっかり押さえておくのがおすすめです。

でも、最初は一度に全てを覚える必要はありません。
「ここのディレクトリはこんなことをするのか」程度で大丈夫です。

簡単なイメージ図と表を載せておきます。

```
/
├── bin
├── boot
├── dev
├── etc
├── home
├── lib
├── media
├── mnt
├── opt
├── proc
├── root
├── sbin
├── sys
├── usr
└── var
```

| ディレクトリ | 役割 |
| :--- | :--- |
| `/`（ルートディレクトリ） | ディレクトリの最上位に位置し、すべてのファイルとディレクトリの起点となっています。 |
| `/bin`(ビン) | 基本的なコマンドが含まれるディレクトリです。例えばlsコマンドやcpコマンドなどのコマンドがここにあります。binは`binary`の略です。 |
| `/boot`(ブート) | システムの起動に関する重要なファイルがここにあります。ユーザーはこのディレクトリを操作するようなことは殆どありません。 |
| `/dev`(デヴ) | デバイスファイルが格納されているディレクトリです。デバイスファイルとはマウスやモニターといったハードウェア機器をファイル化した表したものです。devは`device`の略です。 |
| `/etc`(エトセ) | OSなどのシステム全体の設定ファイルが格納されているディレクトリです。設定ファイルがあるのでとても重要なディレクトリです。etcは`etcetera`の略です。 |
| `/home` | ユーザーのホームディレクトリが格納されているディレクトリです。ホームディレクトリはLinuxにログインした時の最初の場所となるディレクトリのことです。 |
| `/lib`(リブ、ライブラリ) | OSに必要なライブラリファイルが格納されているディレクトリです。ライブラリファイルとはたくさんのプログラムで共有されて使われている特別なファイルで、プログラムが動くために必要な機能やコードが詰まっています。libは`library`の略です。 |
| `/media` | 外部ディスクなどの記憶媒体をLinuxで使用可能にするための登録をシステムが自動で行うためのディレクトリです。 |
| `/mnt`(マウント) | 外部ディスクなどの記憶媒体をLinuxで使用可能にするための登録をユーザーが手動で行うためのディレクトリです。mntは`mount`の略で、mountとは外部ディスクなどの記憶媒体をLinuxで使用可能にするために登録することを意味します。 |
| `/opt`(オプション) | 追加のアプリケーションが格納されているディレクトリです。例えば、Chromeなどのサードパーティアプリケーションをインストールする場所がこの/optです。optは`option`の略です。 |
| `/proc`(プロック) | カーネルなどのOSに関連する情報が格納されているディレクトリです。OSのシステムをコントロールするために使われます。 |
| `/root`(ルート) | システムの管理者であるrootユーザーのホームディレクトリです。ルートディレクトリ「/」とは別物なので注意してください。 |
| `/sbin`(エスビン) | システムの管理者であるrootユーザーのみが実行できるコマンドが含まれているディレクトリです。システムの管理や設定に必要なコマンドがここにあります。sbinは`system binary`の略です。 |
| `/sys`(シス) | OSの現在の状況に関する情報が格納されているディレクトリです。 |
| `/usr`(ユーザー) | 全ユーザーが共通して利用するプログラムやライブラリのデータが格納されているディレクトリです。 |
| `/var`(バー) | ログファイルが格納されているディレクトリです。ログファイルは、コンピューターの動作やアプリケーションの動きを記録するためのファイルです。varは`variable`の略です。 |


## Linuxのコマンドとオプション
OS、Linuxの概念、Linuxの仕組み、Linuxのディレクトリなどを知ったところで、次はLinuxのコマンドとオプションについて説明していきます。

Linuxのコマンドや操作は基本的にCUI（文字ベースの操作）を使って行います。
コマンドを上手に使えるようになるとファイルの管理・システムの監視・ネットワークの確認などが行えるようになります。

初めは基本的なコマンドを押さえて、ファイルの管理の仕方ができるようになることがLinuxの学習の第一歩です。
一つずつ見ていきましょう。

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

```zsh
# 書式
ls オプション ファイル

# lsだけの場合はカレントディレクトリのファイルとディレクトリを表示
ls   
Applications    Library    Pictures    file1    file2

# 複数のディレクトリを指定することもできる
ls / /dev
/:
Applications    Library
/dev:
auditsessions    console    disk0
```

#### 便利なパス名展開
lsコマンドで複数のファイルを指定したい時は、指定したいファイルを引数に並べる必要があり、とても面倒です。
そこでファイル名の一部をパターンで指定することで、複数のファイルを一度に指定することができます。
これを「パス名展開」と言います。

「引数」とはコマンドに渡す値のことをです。
lsコマンドで言うと、ファイル名やディレクトリ名を指します。

パス名展開で使用するのは2つの記号です。
一つは「 `*` (アスタリスク)」で、「任意の文字列を指定する」と言う意味です。
もう一つは「 `?` (クエスチョンマーク)」で、「任意の1文字を指定する」、と言う意味でファイル名の文字数がわかっている場合は「 ? 」を使って絞り込むことができます。「 ? 」は一個につき一文字を表します。

そして、「 * 」や「 ? 」のような特殊な文字のことを「ワイルドカード」と言います。

※ ワイルドカードはファイル名やディレクトリ名を検索する時によく利用されますので覚えておいてください。

| 記号 | 意味 |
| :---: | :--- |
| `*` | 任意の文字列 |
| `?` | 任意の1文字 |

- ワイルドカードを用いた検索の一例
```zsh
# 拡張子がtxtのファイルの一覧を表示
ls *.txt
test.txt    vicopypaste.txt    viinsert.txt

# cから始まり、3文字で終わるファイルを表示
ls /bin/c??
/bin/cat	/bin/csh
```

#### オプションとは？
Linuxのオプションは、コマンドの動きに追加の機能を指定したり、本来のコマンドの動きとは違った動きを指定するものです。
オプションは、「`-`」ハイフンの後に文字や記号を付けて記述します。

- オプションのいろいろな書き方
```zsh
# 書き方①コマンドの後ろに半角スペースで区切って指定する
ls -a

# 書き方②オプションは2つ以上指定することができる
ls -a -l

# 書き方③オプションは2つ以上指定する場合、一つにまとめることができる
ls -al

# 書き方④オプションとコマンドの引数を同時に指定できる
ls -al /

# 書き方⑤「--」で始まるロングオプションがある
ls --version
```

- lsコマンドでは主に以下のオプションが用いられます
```zsh
# lsコマンドに用いられるオプション
-l:ファイルの詳細情報（ファイルタイプ・ファイルモード・リンク数・所有者・所有グループ・サイズ・タイムスタンプ・ファイル名ディレクトリ名）を表示します。
-a:「.」ドットで始まる隠しファイルも含めた全て(all)のファイルを表示します。※隠しファイルとはファイル名が「.」ドットから始まるファイルのことで、通常はlsコマンドだけでは表示されません。
-t:ファイルやディレクトリの最終更新時間順(time)に表示します。
-r:逆の順序(reverse)でファイルやディレクトリを表示します。
```

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `ls` | ファイルやディレクトリの一覧を表示するコマンドです。 |
| `ls -l` | ファイルの詳細情報（ファイルタイプ・ファイルモード・リンク数・所有者・所有グループ・サイズ・タイムスタンプ・ファイル名ディレクトリ名）を表示します。 |
| `ls -a` | 「.」ドットで始まる隠しファイルも含めた全て(all)のファイルを表示します。※ 隠しファイルとはファイル名が「.」ドットから始まるファイルのことで、通常はlsコマンドだけでは表示されません。 |
| `ls -t` | ファイルやディレクトリの最終更新時間順(time)に表示します。 |
| `ls -r` | 逆の順序(reverse)でファイルやディレクトリを表示します。 |

### cdコマンド
ディレクトリを移動するコマンドです。
cdは `change dhirectory` の略です。
cdコマンドではオプションを使うことは滅多にありません。

```zsh
# 書式
cd オプション ディレクトリ

# 例
cd /Users/yoshiwo
```

- cdコマンドを用いた特別なディレクトリへの移動方法

| コマンド (+ 特別なディレクトリを指定) | 説明 |
| :--- | :--- |
| `cd` | ディレクトリを移動するコマンドです。 |
| `cd ..` | 1つ上の階層のディレクトリに移動します。 |
| `cd ~` | ホームディレクトリ(Linuxにログインした時の最初に位置するディレクトリ)に移動します。 |
| `cd /` | ルートディレクトリに移動します。 |

### pwdコマンド
自分が現在いるディレクトリ（カレントディレクトリ）を表示するコマンドです。
今いるディレクトリが分からない時は pwdコマンドで確認しましょう。
pwdは `print name of working directory` の略です。
cdコマンド同様、オプションを使うことは滅多にありません。

```zsh
# 書式
pwd オプション

# 例
pwd
/Users/yoshiwo
```

| コマンド | 説明 |
| :--- | :--- |
| `pwd` | 自分が現在いるディレクトリ（カレントディレクトリ）を表示するコマンドです。 |

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

```zsh
# 書式
mkdir オプション 作成するディレクトリ名

# 例） testディレクトリを作成する
mkdir test
```
※ ディレクトリ名は日本語だと文字化けしたりする恐れがあるので、英語で作成するのがおすすめです。

#### 必要なディレクトリ階層を一度に作成する
mkdirコマンドに`-p`オプションを付けると、親ディレクトリも含めて、必要なディレクトリ階層を一度に作成することができます。
例えばphotosディレクトリの中にsummerというディレクトリを作りたい場合、普通は次のように書く必要があります

```zsh
# photosディレクトリの中にsummerディレクトリを作成
mkdir photos
cd photos
mkdir summer
```

しかし、「-p」オプションを使うと1行で簡単に作成できます。
```zsh
# photosディレクトリの中にsummerディレクトリを作成
mkdir -p photos/summer
```

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `mkdir` | ディレクトリを作成するコマンドです。 |
| `mkdir -p` | 親ディレクトリも含めて、必要なディレクトリ階層を一度に作成します。 |

### rmdirコマンド
空のディレクトリを削除するコマンドです。
空のディレクトリとは、中にファイルやディレクトリが含まれていないディレクトリのことを指します。
rmdirは `remove directory` の略です。

```zsh
# 書式
rmdir ディレクトリ名

# 例
rmdir test
```

※ 空ではないディレクトリを削除しようとするとエラーになります。それは中にファイルが残っていることを気付かずにディレクトリを削除してしまうのを防ぐためです。

| コマンド | 説明 |
| :--- | :--- |
| `rmdir` | 空のディレクトリを削除するコマンドです。 |

### catコマンド
ファイルの内容を表示するコマンドです。
catは `concatenate` の略です。

```zsh
# 書式
cat オプション ファイル名

# 例
cat /etc/hosts
127.0.0.1 localhost
::1       localhost
```

- catコマンドでは主に以下のオプションが用いられます
```zsh
-n:行番号を付加して表示します。

# 例
cat /etc/hosts
1 127.0.0.1	localhost
2 ::1       localhost
```

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `cat` | ファイルの内容を表示するコマンドです。 |
| `cat -n` | ファイルの内容に行番号を付加して表示します。 |

### less
ファイルの中身をスクロール表示するコマンドです。
たくさんのコードが書かれたファイルの中身を開く時に便利なコマンドです。

```zsh
# 書式
less オプション ファイル名

# 例
less /etc/bashrc_Apple_Terminal

# 例えば上記のコードを実行すると以下のように長いファイルの中身がスクロール画面で表示されます
# bash support for Terminal.

# Working Directory
#
# Tell the terminal about the current working directory at each prompt.

if [ -z "$INSIDE_EMACS" ]; then
    update_terminal_cwd() {
        # Identify the directory using a "file:" scheme URL, including
        # the host name to disambiguate local vs. remote paths.
        
        # Percent-encode the pathname.
        local url_path=''
        {
            # Use LC_CTYPE=C to process text byte-by-byte and
            # LC_COLLATE=C to compare byte-for-byte. Ensure that
            # LC_ALL and LANG are not set so they don't interfere.
            local i ch hexch LC_CTYPE=C LC_COLLATE=C LC_ALL= LANG=
            for ((i = 0; i < ${#PWD}; ++i)); do
                ch="${PWD:i:1}"
                if [[ "$ch" =~ [/._~A-Za-z0-9-] ]]; then
                    url_path+="$ch"
                else
                    printf -v hexch "%02X" "'$ch"
                    # printf treats values greater than 127 as
                    # negative and pads with "FF", so truncate.
                    url_path+="%${hexch: -2:2}"
                fi
            done
        }
        
        printf '\e]7;%s\a' "file://$HOSTNAME$url_path"
    }
    PROMPT_COMMAND="update_terminal_cwd${PROMPT_COMMAND:+; $PROMPT_COMMAND}"
fi
.
.
.
```

- lessコマンド時のスクロール画面の操作は以下の通りです

| 操作方法 | 内容 |
| :--- | :--- |
| `スペースキー` または `F` | 画面下にスクロール移動します。 |
| `B` | 画面上にスクロール移動します。 |
| `J` | 1行下にスクロール移動します。 |
| `K` | 1行上にスクロール移動します。 |
| `Q` | lessコマンド(スクロール画面)を終了します。 |

- 更にlessコマンドでファイルの中身を表示した際に、特定の文字列を検索して確認することもできます

| 操作方法 | 内容 |
| :--- | :--- |
| `/検索したい文字列` | 下方向に向かって文字列を検索します。 |
| `?検索したい文字列` | 上方向に向かって文字列を検索します。 |
| `文字列を検索後にn` | 検索した文字列の次の検索結果に移動します。 |
| `文字列を検索後にN` | 検索した文字列の前の検索結果に移動します。 |

### headコマンドとtailコマンド
ファイルの中身の先頭を確認したい場合は `head` コマンドを、ファイルの中身の末尾を確認したい時は `tail` コマンドを使用します。
headコマンド、tailコマンド共に書式やよく用いられるオプションは同じです。

- オプションを用いない場合
    - headコマンドの場合は、先頭から10行を表示します
    - tailコマンドの場合は、末尾から10行を表示しま。

```zsh
# 書式
head オプション ファイル名
tail オプション ファイル名

# 例:headコマンドでFILEファイルの先頭10行を表示する
head FILE

# 例:tailコマンドでFILEファイルの末尾10行を表示する
tail FILE
```

- headコマンドでは主に以下のオプションが用いられます

```zsh
-n 行数:ファイルの先頭から指定した行数を表示します。
-c バイト数:ファイルの先頭から指定したバイト数を表示します。
```

- tailコマンドでは主に以下のオプションが用いられます

```zsh
-n 行数:ファイルの末尾から指定した行数を表示します。
-c バイト数:ファイルの末尾から指定したバイト数を表示します。
-f ファイル名:ファイルに新しい内容が追加されるたびに自動的に表示を更新します。主にログファイルの監視などに使われます。
```

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `head` | ファイルの中身の先頭から10行を表示します。 |
| `head -n 行数` | ファイルの先頭から指定した行数を表示します。 |
| `head -c バイト数` | ファイルの先頭から指定したバイト数を表示します。 |
| `tail` | ファイルの中身の末尾から10行を表示します。 |
| `tails -n 行数` | ファイルの末尾から指定した行数を表示します。 |
| `tail -c バイト数` | ファイルの末尾から指定したバイト数を表示します。 |
| `tail -f` | ファイルに新しい内容が追加されるたびに自動的に表示を更新します。主にログファイルの監視などに使われます。 |

### touchコマンド
`touch`コマンドは空の新しいファイルを作成したり、既存のファイルの更新日時を変更するコマンドです。

```zsh
# 書式:空の新しいファイルを作成する場合
touch 新しいファイル名

# 書式:既存のファイルの更新日時を現在の日時に変更する場合
touch 既存のファイル名
```

| コマンド | 説明 |
| :--- | :--- |
| `touch 新しいファイル名` | 空の新しいファイルを作成します。 |
| `touch 既存のファイル名` | 既存のファイルの更新日時を現在の日時に変更します。 |

### rmコマンド
作成したファイルを削除するコマンドです。
rmは `remove` の略です。

```zsh
# 書式
rm オプション 削除するファイル名

# 例
rm file.txt
```

※ rmコマンドを実行すると、対象のファイルはゴミ箱には行かず、完全に削除されますので注意してください。

- rmコマンドでは主に以下のオプションが用いられます

```zsh
-i:削除を行う時の確認をします。対象のファイルを本当に削除してよいのか、確認のための問い合わせをします。これは誤って削除することを防ぐために利用されます。
-f:強制的に削除を実行します。ファイルによっては、削除に確認を求められる場合がありますが、このオプションはその確認を無視して強制的に削除を行います。
-r:ディレクトリを対象に削除を行います。※ディレクトリの中のファイルやディレクトリも削除されます。
```

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `rm` | 作成したファイルを削除するコマンドです。 |
| `rm -i` | 削除を行う時の確認をします。 |
| `rm -f` | 確認を無視して強制的に削除を実行します。 |
| `rm -r` | ディレクトリを対象に削除を行います。 |

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

```zsh
# 書式:ファイルの移動
mv 移動元のファイル 移動先のファイル

# 例
mv file1 file2
```

※ ここで注意してもらいたいのが移動元と移動先が、「ファイルと存在しないファイル」「ファイルとディレクトリ」「ディレクトリとディレクトリ」それぞれの組み合わせ次第でmvコマンドの内容が変わってしまう点です。ちなみに、ディレクトリなのかファイルなのかはシステムが自動的に判断します。

- 表にまとめました

| コマンド | 移動元 | 移動先 | rmコマンドの内容 |
| :--- | :--- | :--- | :--- |
| `mv` | ファイル | 存在しないファイル | 移動元のファイル名が、移動先のファイル名に変更します。 |
| `mv` | ファイル | ディレクトリ | 移動元のファイルは、移動先のディレクトリに移動します。 |
| `mv` | ディレクトリ | ディレクトリ | 移動元のディレクトリは、移動先のディレクトリに移動します。 |

- mvコマンドでは主に以下のオプションが用いられます

```zsh
-i:処理を行う時の確認をします。対象のファイルを本当に削除してよいのか、確認のための問い合わせをします。これは誤って削除することを防ぐために利用されます。
-f:強制的に移動や名前の変更を実行します。一部の処理では、mvコマンドが確認を求められる場合がありますが、このオプションはその確認を無視して強制的に処理を行います。
```

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `mv` | ファイルの移動、ファイル名の変更を行うコマンドです。 |
| `mv -i` | 移動や名前の変更を行う時の確認をします。 |
| `mv -f` | 確認を無視して強制的に移動や名前の変更を実行します。 |

### cpコマンド
ファイルをコピーするコマンドです。
cpは `copy` の略です。

```zsh
# 書式
cp オプション コピー元 コピー先

# 例
file1 file2
```

※ 先程のmvコマンドと同じようにコピー元とコピー先が「ファイルと存在しないファイル」「ファイルと既存ファイル」「ファイルとディレクトリ」それぞれの組み合わせ次第でcpコマンドの内容が変わってしまいます。こちらも、ディレクトリなのかファイルなのかはシステムが自動的に判断します。

- 表にまとめました

| コマンド | コピー元 | コピー先 | cpコマンドの内容 |
| :--- | :--- | :--- | :--- |
| `cp` | ファイル | 存在しないファイル | コピー元の中身をコピーして、コピー先のファイル名でファイルが作成されます。 |
| `cp` | ファイル | 既存ファイル | コピー元の中身を、コピー先に上書きします。 |
| `cp` | ファイル | ディレクトリ | ディレクトリの下にコピー元のファイルが作成されます。 |

- cpコマンドでは主に以下のオプションが用いられます

```zsh
-i:処理を行う時の確認をします。ファイルを上書きコピーしてよいのか、確認のための問い合わせをしてきます。これは誤って上書きコピーすることを防ぐために利用されます。
-r:ディレクトリをコピーします。cpコマンドは基本的にファイルをコピーする機能なのでコピー元がディレクトリだとエラーが発生してしまいます。-rオプションを付けると、ディレクトリをコピーすることができるようになります。
```

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `cp` | ファイルをコピーするコマンドです。 |
| `cp -i` | コピーを行う時の確認をします。 |
| `cp -r` | ディレクトリをコピーします。 |

### lnコマンド
リンクを張るコマンドです。
lnは `link` の略です。

```zsh
# 書式
ln オプション リンク元ファイル名 リンク名

# 例:ハードリンクを作成
ln file1 file2

# 例:シンボリックリンクを作成
ln -s file1 file2
```

#### 「リンクを張る」とは？
Linuxではファイルに別名を付けることができ、別名を付けることを「リンクを張る」と言います。
業界特有の表現だと思ってください。

そして、このリンクには2種類のリンクが存在しています。
それが「ハードリンク」と「シンボリックリンク」です。

#### ハードリンクとは？
- 1つのファイルの実体に複数の名前をつける機能です
- 元のファイルを削除しても消えません
- 削除が必要な場合は全てのファイル（ハードリンク）を消す必要があります

#### シンボリックリンクとは？
- リンク先のパス名が書かれた特殊なファイルのことです
- リンク先がファイルの実体です
- シンボリックリンクを消しても何も影響はありません
  何故なら、シンボリックリンクはリンク先のパス(道筋)名を記載しただけだからです
- 逆にシンボリックリンクを残したままファイルの実体を削除したり、ファイル自体を別の場所に移動させてしまうとファイルを参照できなくなります
  何故なら、ファイルの実体が無ければ行くことはできないですし、ファイル自体が別の場所に移動すればパス（道筋）も変わってしまうからです

#### リンクを使用するタイミング
実際にリンクを使う時の一例を挙げてみました。
- 例） 長いパス名を省略したい時

例えば、`/home/user/documents/projects/project1/......`とディレクトリやファイルが深い階層にあると、指定するたびに長たらしいパス名を入力しなければなりません。それはとても面倒で時間が掛かってしまいます。
そこで、リンクを使用すると設定したディレクトリ名やファイル名だけで簡単にアクセスできます。

※ ハードリンクとシンボリックリンクでは、シンボリックリンクのほうが使用することが多いです。それは、ハードリンクにはいくつか制限があるため使いにくいからです。逆にシンボリックリンクはそのような制限がないのでリンクとして使いやすいのです。

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `ln` | リンクを張る(ハードリンクを作成する)コマンドです。 |
| `ln -i` | シンボリックリンクを作成します。 |

### findコマンド
ファイルがどこにあるのか検索するコマンドです。

```zsh
# 書式
find 検索開始ディレクトリ 検索条件 アクション

# 例
find . -name file.txt -print
./documents/.../file.txt
```
#### find . -name file.txt -print の解説
- `.` ：検索開始ディレクトリ(例では、「 `.` 」カレントディレクトリを指定しています)
- `-name file.txt` ：検索条件
- `-print` ：検索アクション
- findコマンドを実行すると、「①カレントディレクトリを起点にして / ②file.txtという名前のファイルを探して、ファイル名が「file.txt」のファイルを見つけたら / ③-print(パスを表示すること)を実行する」という意味になります。
- 「 -print 」はfindコマンドで最も使う検索アクションで「パス名を表示」します。
- ちなみに検索アクションを指定しない場合は「 -print 」が指定された時と同じ動作を行います。そのため、実は例のコードの「 -print 」は省略することができます。

#### よく使われる検索条件
##### -name
- ファイル名を指定してファイルを検索します。
- ファイル名の大文字小文字は区別します。
- 「 * 」や「 ? 」などのワイルドカードを組み合わせて使えます。
- 「 * 」を使って指定する際は、検索条件を「 `' '` 」(シングルクォーテーション)または「 `" "` 」(ダブルクォーテーション)で囲います。

| 記号 | 意味 |
| :---: | :--- |
| `*` | 任意の文字列 |
| `?` | 任意の1文字 |

```zsh
# 例
find . -name file.txt

# -nameはワイルドカードと組み合わせて使うことができ、「*」を使用して指定する際は「''または""」で囲むこと
find . -name "*.txt" -print   # 拡張子が「.txt」であるファイルを検索する、という意味で、検索結果が下に表示されます
./Desktop/webtext-sample/readme.txt
./Desktop/shellscript_lessons/colors.txt
./Desktop/Training/text.txt
```

##### -iname
- ファイル名を指定してファイルを検索します。
- ファイル名の大文字小文字は区別しません。

```zsh
# 例
find . -iname file.txt
./Desktop/documents/FILE.txt
./Desktop/pictures/File.txt
./Desktop/sample_git/file.txt
```

##### -type
- ファイルの種類で検索します。
- ファイルの種類は通常のファイルの「`f`」、シンボリックリンクの「`l`」、ディレクトリの「`d`」の3つです。

```zsh
# -type f は 通常のファイルを検索
find . -type f -print

# -type l は シンボリックリンクを検索
find . -type l -print

# -type d は ディレクトリを検索
find . -type d -print
```

##### -a
- 複数の検索条件を指定します。
- 「-a」は省略することができます。

```zsh
# 例
find . -type d -a -name TEST -print
```

これは、「ファイルの種類がディレクトリ」と「TESTという名前」の両方の条件を満たすディレクトリを検索することを意味します。
つまり「TESTという名前のディレクトリを検索して、（見つかったら）パス名を表示して」ということになります。

ちなみに「-a」のaは論理積[^4]であるANDの頭文字です。
[^4]:論理積：コンピュータやプログラミングで条件を組み合わせる際によく使われる概念です。今は「論理積はANDのことなんだ」ぐらいの認識で大丈夫です。

| コマンド | 検索条件 | 説明 |
| :--- | :--- | :--- |
| `find` | `-name` | 大文字小文字を区別して指定した名前を検索します。 |
| `find` | `-iname` | 大文字小文字を区別せずに指定した名前を検索します。 |
| `find` | `-type f` | 通常のファイルを検索します。 |
| `find` | `-type l` | シンボリックリンクを検索します。 |
| `find` | `-type d` | ディレクトリを検索します。 |
| `find` | 検索条件1 `-a` 検索条件2 | 検索条件1 且つ 検索条件2 を満たしたものを検索します。 |

### chmodコマンドを学ぶ前に
chmodコマンドを理解するために知っておきたい概念が大きく2つあります。それが、
**1. ファイルのオーナーとグループ**
**2. パーミッション**
です。それぞれについて説明した後、chmodコマンドについて言及していきます。

#### 1. ファイルのオーナーとグループ
そもそもLinuxではデータは全て「 ファイル 」という形式で作られています。
全てのファイルには「所有者」を意味する**オーナー**、**グループ**が設定されていて
**「オーナーが、どのような操作をできるのか」**
**「グループが、どのような操作をできるのか」**
を設定することで、権限が管理されています。

オーナーとはファイルやディレクトリの所有者を指します。
オーナーはファイルやディレクトリを作成したユーザーであり、そのファイルやディレクトリに対して特定の権限を持ちます。

グループとは複数のユーザーをまとめて管理するための仕組みです。
複数のユーザーが同じグループに所属することで、同じ権限を共有したり、ファイルやディレクトリの共有を行うことができます。


- `ls -l コマンド` でファイルのオーナーとグループを確認することができます。　

```zsh
# ls -lコマンドで表示された「yoshiwo」はオーナーの項目、「staff」はグループの項目です
ls -l ~/loop
-rwxr-xr-x  1 yoshiwo  staff  59  7 19 13:29 /Users/yoshiwo/loop
```
![スクリーンショット 2023-07-30 15.38.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599480/6f66aec7-5f3c-e5b2-578e-155459623119.png "ls -lコマンドの詳細")

上の画像では、「yoshiwo」 は loopファイルの**オーナー**(左側)で、「staff」 は loopファイルの**グループ**(右側)を意味します。

#### 2. パーミッション
パーミッションとはファイルやディレクトリに対するアクセス権限を制御する仕組みです。
ファイルやディレクトリにはオーナー、グループ、その他のユーザーの3つのユーザーが存在し、それぞれに対して①read（読み取り）、②write（書き込み）、③execute（実行）の3つの権限が設定されています。

具体的には、以下のような形でパーミッションが表現されます。

- r (読み取り)：ファイルの内容を読み取ることができます
- w (書き込み)：ファイルに書き込むことができます
- x (実行)：ファイルを実行することができます

これらの権限は、オーナー、グループ、その他のユーザーごとに個別に設定されます。
例えば、所有者が r (読み取り)と w (書き込み)の権限を持ち、グループとその他のユーザーは r (読み取り)のみ許可されるといった設定ができます。
また、ディレクトリに対しても同様にパーミッションを設定することができます。

##### パーミッションの確認方法と読み方
ファイルのオーナーとグループの時と同じように `ls -l コマンド` でファイルやディレクトリのパーミッションを確認することができます。

```zsh
# rwxr-xr-xがパーミッションです
ls -l ~/loop
-rwxr-xr-x  1 yoshiwo  staff  59  7 19 13:29 /Users/yoshiwo/loop
```
![スクリーンショット 2023-07-30 15.22.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599480/02df7781-e426-461e-4ac0-ee2b6f1a678d.png "ls -lコマンド パーミッションの確認")

`ls -l コマンド` で表示された `-rwxr-xr-x` の読み方ですが、1文字目の「 `-` (ハイフン)」がある場所は**ファイルタイプ**（ファイルの種類）の項目です。findコマンドの検索条件 -type と似ているのですが、

- 「 `-` 」は 通常のファイル
- 「 `l` 」は シンボリックリンク
- 「 `d` 」は ディレクトリ

を意味します。1文字目は「 - 」なので通常のファイルだと分かります。

1文字目の「-」の後ろの9文字 `rwxr-xr-x` がパーミッションです。
パーミッションは `rwx` / `r-x` / `r-x` と3文字1セットが3つ連なっていて、

- 最初の3文字(2・3・4文字目) `rwx` が オーナーのパーミッション
- 次の3文字(5・6・7文字目) `r-x` が グループのパーミッション
- その次の3文字(8・9・10文字目) `r-x` が その他のユーザーのパーミッション

を意味しています。

##### ファイル(ディレクトリ)への権限とその種類
パーミッションに表示された `r` `w` `x` の記号はファイル（ディレクトリ）への権限を意味します。
ちなみに `-` は権限がないことを意味します。

- パーミッション

| 記号 | 権限 | 略 |
| :---: | :--- | :--- |
| `r` | 読み取り | **r**ead |
| `w` | 書き込み | **w**rite |
| `x` | 実行 | e**x**ecute |
| `-` | 権限がない | --- |

- ファイルへの操作

| 記号 | 意味 |
| :---: | :--- |
| `r` | read (読み取り) : ファイルの内容を読み取ることができます。 |
| `w` | write (書き込み) : ファイルに書き込むことができます。 |
| `x` | execute (実行) : ファイルを実行することができます。 |

- ディレクトリへの操作

| 記号 | 意味 |
| :---: | :--- |
| `r` | read (読み取り) : ディレクトリを読み取ることができます。 |
| `w` | write (書き込み) : ディレクトリに書き込むことができます。 |
| `x` | execute (実行) : ディレクトリに登録されているファイルへのアクセスができます。 |

先程の `rwxr-xr-x` は以下のようになります。

| 権限を許可する対象 | read (読み取り) | write (書き込み) | execute (実行) |
| :--- | :---: | :---: | :---: |
| オーナー `rwx` | ⭕️　許可 | ⭕️　許可 | ⭕️　許可 |
| グループに属するユーザー `r-x` | ⭕️　許可 | ❌ 権限がない | ⭕️　許可 |
| その他のユーザー `r-x` | ⭕️　許可 | ❌ 権限がない | ⭕️　許可 |

### chmodコマンド - 記号での指定 -
ファイルのオーナーとグループ、パーミッションについて知った上で`chmod`コマンドについて説明します。
`chmod`コマンドはファイルやディレクトリのパーミッションを設定するコマンドです。
chmodは `change mode` の略です。

```zsh
# 書式
chmod [u、g、o、a] [+、-、=] [r、w、x] ファイル名

# 例
chmod u+x test.txt
```

「`u` 、`g` 、`o` 、`a`」はそれぞれパーミッションを設定する対象を示す記号、「`+` 、`-` 、`=`」は権限の追加・削除・設定を示す記号、「`r` 、`w` 、`x`」は先程の説明にもありましたが、ファイル（ディレクトリ）への権限の内容を示します。

- 設定対象ユーザー

| 記号 | 意味 | 英語名 | 説明 |
| :--- | :--- | :--- | :--- |
| `u` | ユーザー | **U**ser | 所有者に対するパーミッションを設定する。 |
| `g` | グループ | **G**roup | グループに対するパーミッションを設定する。 |
| `o` | その他のユーザー | **O**thers | その他のユーザーに対するパーミッションを設定する。 |
| `a` | すべてのユーザー | **A**ll | u、g、oすべてのユーザーに対するパーミッションを設定する。 |

- 権限の追加・削除・設定

| 記号 | 意味 | 説明 |
| :---: | :--- | :--- |
| `+` | 権限を追加する | 指定したパーミッションを追加する。 |
| `-` | 権限を削除する | 指定したパーミッションを削除する。 |
| `=` | 権限を設定する | 指定したパーミッションを設定する。 |

- パーミッション

| 記号 | 権限 |
| :---: | :--- |
| `r` | read(読み取り) |
| `w` | write(書き込み) |
| `x` | execute(実行) |

つまり
- `u` 、`g` 、`o` 、`a` は 「誰に対して」
- `+` 、`-` 、`=`   は 「どうするのか」
- `r` 、`w` 、`x`   は 「何を」

を表します。

- 例の `chmod u+x test.txt` を見てみましょう。
![スクリーンショット 2023-07-31 10.53.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599480/5cdd0d12-c426-455f-e0f4-53ddda517c43.png "Chmod u+x test.txtの意味")

- 誰に対して : `u` ユーザー
- どうするのか : `+` 権限（パーミッション）を追加する
- 何を : `x` 実行（を）

以上から「test.txtファイルにおいて、ユーザー（u）に / 実行（e）する権限（パーミッション）を / 追加する（+）」という意味になります。

「 誰に対して / どうするのか / 何の権限を 」を記号で組み合わせて書くのが、`chmod`コマンドの書き方です。

#### 「 + 」と「 = 」の違い
「+」は追加、「=」は設定。どちらも同じ意味なのでは？と思いたくなりますが、実際に挙動を確かめてみると一目瞭然です。
test.txtファイルを例に見ていきます。

- 「+」の挙動
![スクリーンショット 2023-08-01 8.06.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599480/a4e48d86-b528-640d-563a-018088cf71f8.png "「+」の挙動")


- 「=」の挙動
![スクリーンショット 2023-08-01 8.08.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599480/6370c065-4152-83d2-8a5f-be45c0955566.png "「-」の挙動")


「+」は、指定したパーミッションを追加します。既存のパーミッションに対して新しいパーミッションを追加します。つまり、既存のパーミッションは変更されず、新しいパーミッションが追加されます。

「=」は、指定したパーミッションを設定します。既存のパーミッションを無視して、新しくパーミッションを設定します。つまり、既存のパーミッションは全て上書きされます。

まとめると

- 「+」は既存のパーミッションに新しいパーミッションを追加する
- 「=」は既存のパーミッションを無視して新しくパーミッションを設定する

のが、「+」と「=」の違いです。

### chmodコマンド - 数字での指定 -
実はパーミッションには数字が割り振られています。
chmodコマンドはその割り振られた数字を使って指定することもできます。

```zsh
# 書式
chmod 8進数3桁の表記 ファイル名

# 例
chmod 754 test.txt
```

8進数は0から7までの数字を使って表現される数の表記方法です。
パーミッションに割り振られた数字を3桁で表記することで具体的な権限の指定を行うことができます。

- パーミッションに割り振られている数字

| 記号 | 権限 | 割り振られている数字 |
| :---: | :--- | :---: |
| `r` | read(読み取り) | 4 |
| `w` | write(書き込み) | 2 |
| `x` | execute(実行) | 1 |

r（読み込み）には「4」、w（書き込み）には「2」、x（実行）には「1」が割り振られています。
上記の合計値を「オーナー」「グループ」「その他のユーザー」の順で入力するとパーミッションを変更することができます。

例の `chmod 754 test.txt` では

- オーナーに read(4) と write(2) と execute(1) の権限が追加されて、 4 + 2 + 1 = 7
- グループに read(4) と execute(1) の権限が追加されて、 4 + (0) + 1 = 5
- その他のユーザーに read(4) の権限が追加されて、 4 + (0) + (0) = 4

となり、この数字を記号に直すと　

- オーナーは read と write と execute が付与されて rwx
- グループは read と execute が付与されて r-x
- その他のユーザーは read が付与されて r--

よって 754 は rwx r-x r-- を意味します。

- パーミッションの記号と文字の表記をいくつか

| 記号 | ユーザー　| グループ | その他のユーザー | 8進数の3桁 |
| :---: | :---: | :---: | :---: | :---: |
| rwx rwx rwx | 4 + 2 + 1 = 7 | 4 + 2 + 1 = 7 | 4 + 2 + 1 = 7 | `777` |
| rwx r-x r-x | 4 + 2 + 1 = 7 | 4 + (0) + 1 = 5 | 4 + (0) + 1 = 5 | `755` |
| rw- --- --- | 4 + 2 + (0) = 6 | (0) + (0) + (0) = 0 | (0) + (0) + (0) = 0 | `600` |

- パーミッション早見表

| 記号 | 権限 | 数字の割り振り | 8進数 |
| :---: | :--- | :--- | :---: |
| rwx | 読み取り 書き込み 実行 | 4 + 2 + 1 | 7 |
| rw- | 読み取り 書き込み | 4 + 2 | 6 |
| r-x | 読み取り 実行 | 4 + 1 | 5 |
| r-- | 読み取り | 4 | 4 |
| -wx | 書き込み 実行 | 2 + 1 | 3 |
| -w- | 書き込み | 2 | 2 |
| --x | 実行 | 1 | 1 |

数字での指定がどのようにされるのか「何となくわかってきたかな」と思います。
初めは慣れない表記に戸惑うこともありますが、この方法は簡潔で便利なため、覚えておくと役立ちます。

### chownコマンド
ファイルの所有者や所有グループを変更するコマンドです。
chownは `chamge owner` の略です。

```zsh
# 書式:ファイルの所有者を変更する
chown オプション ユーザー ファイル

# 例:test.txtファイルの所有者をuserに変更する
chown user test.txt

# 書式:ファイルの所有グループを変更する
chown オプション :グループ ファイル

# 例:test.txtファイルの所有グループをmembers（グループ）に変更する
chown :members test.txt
```

- chownコマンドでは主に以下のオプションが用いられます。

```zsh
-R:指定したディレクトリとそのディレクトリ以下のファイルやディレクトリの所有権も変更します。
```

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `chown` | ファイルの所有者や所有グループを変更するコマンドです。 |
| `chown -R` | 指定したディレクトリとそのディレクトリ以下のファイルやディレクトリの所有権も変更します。 |

### psコマンド
実行中のプロセスを表示するコマンドです。
現在コンピュータ上で何が実行されているかを確認します。
psは `process status` の略です。

プロセスとは、コンピューター上で実行されるプログラムのことです。
例えば、Webブラウザを開いている時や音楽を再生している時など、それぞれの活動は1つのプロセスとして管理されます。

```zsh
# 書式
ps オプション

# 例
ps
 PID TTY           TIME CMD
1543 ttys000    0:00.32 -zsh
```

psコマンドを実行すると、`PID`、`TTY`、`TIME`、`CMD`が表示されます。

- PID：PIDは、プロセスIDの略で、各プロセスを識別する番号です。コンピューター上で実行されるすべてのプロセスには、それぞれ異なるPIDが割り当てられています。この番号によって、どのプロセスがどの活動を行なっているのかを識別することができます。
- TTY：TTYは、プロセスが実行されているターミナルの名前を示します。
- TIME：プロセスがCPUを使用して実行された時間の合計を示します。プロセスが実行されるたびに、時間が増えていきます。TIMEの値が大きいほど、そのプロセスに長い間実行されていることを意味します。
- CMD：実行しているコマンドを示します。

| 項目 | 内容 |
| :--- | :--- |
| PID | プロセスID |
| TTY | ターミナル名 |
| TIME | プロセスがCPUを使用した時間 |
| CMD | 実行したコマンドやプログラム名 |

#### psコマンドのオプションについて
psコマンドにはたくさんのオプションが存在しています。
中でもよく使われているものを一つ紹介します。

```zsh
# auxはオプションですが、「-」を付けなくていいです
aux：すべてのユーザーのプロセスを、詳細情報に合わせて表示します。

# 例
ps aux
USER               PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND
_windowserver      154   8.5  0.9 37435060 146192   ??  Ss   月01PM 210:50.04 /System/Library/……
yoshiwo           1540   3.1  1.0 34676368 169448   ??  S    月04PM   0:55.14 /System/Applications/……
root              7848   0.0  0.1 33773720  20824   ??  Ss   10:04AM   0:12.34 /usr/libexec/……
```
auxオプションの `a` はすべてのユーザーのプロセスを表示、`u` は詳細情報を表示、`x` はユーザーのすべてのプロセスを表示、という意味です。

- auxオプションで表示される各項目について

| 項目 | 内容 |
| :--- | :--- |
| USER | プロセスを実行しているユーザー名 |
| PID | プロセスID |
| %CPU | プロセスのCPU使用率 |
| %MEN | プロセスのメモリ使用率 |
| VSZ | プロセスが使用している仮想メモリのサイズ |
| RSS | プロセスが使用している物理的なメモリのサイズ |
| TT | ターミナル名 |
| STAT | プロセスの状態 |
| STARTED | プロセスを開始した時刻 |
| TIME | CPUの使用時間 |
| COMMAND | 実行中のコマンド |

| コマンド (+ オプション) | 説明 |
| :--- | :--- |
| `ps` | 実行中のプロセスを表示するコマンドです。 |
| `ps aux` | すべてのユーザーのプロセスを、詳細情報に合わせて表示します。 |

### killコマンド
プロセスに対してシグナルを送るためのコマンドです。
シグナルを送られたプロセスは終了します。

例えば、突然プロセスが動かなくなってしまった場合、そのプロセスに対してシグナルを送ると、強制的にプロセスを終了させることができます。

killコマンドはプロセスを終了させたい時に使うことが多いので、先ずはkillコマンドでプロセスを終了させる流れを覚えることが大事です。

```zsh
# 書式
kill PID   または   kill -シグナル番号 PID   または   kill -シグナル名 PID
```

- シグナル：実行中のプロセスを制御する信号のようなものです。シグナルには、シグナル番号とシグナル名が割り振られています。`kill -l` コマンドでシグナルの種類を確認することができます。

```zsh
# シグナルの種類を表示
kill -l
# 数字がシグナル番号、アルファベットの文字列がシグナル名
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL
 5) SIGTRAP	 6) SIGABRT	 7) SIGEMT	 8) SIGFPE
 9) SIGKILL	10) SIGBUS	11) SIGSEGV	12) SIGSYS
13) SIGPIPE	14) SIGALRM	15) SIGTERM	16) SIGURG
17) SIGSTOP	18) SIGTSTP	19) SIGCONT	20) SIGCHLD
21) SIGTTIN	22) SIGTTOU	23) SIGIO	24) SIGXCPU
25) SIGXFSZ	26) SIGVTALRM	27) SIGPROF	28) SIGWINCH
29) SIGINFO	30) SIGUSR1	31) SIGUSR2

# この2つのコマンドは同じ
kill -15 PID
kill -SIGTERM PID
```

- 代表的なシグナル

| シグナル番号 | シグナル名 | 動作（※） | 意味 |
| :---: | :---: | :---: | :--- |
| 1 | SIGHUP | Term | 制御端末の切断、ハングアップ （Hang Up） |
| 2 | SIGINT | Term | キーボードからの割り込みのシグナル |
| 3 | SIGQUIT | Core | キーボードによる中止のシグナル |
| 9 | SIGKILL | Term | 強制終了のシグナル（PCの電源をいきなり切るイメージ） |
| 15 | SIGTERM | Term | 終了のシグナル（killコマンドのデフォルトのシグナル） |

※ 「動作」はシグナルを受け取った際の動作で、デフォルトは以下のとおりです。TermやCoreの他にIgnore、Stop、Contもあります。実際にどのような動作になるかは、コマンドによって異なります。
| 動作 | 意味 |
| :--- | :--- |
| Term | プロセスの終了 |
| Ignore | 無視 |
| Core | プロセスの終了とコアダンプ出力 |
| Stop | プロセスの一時停止 |
| Cont | プロセスが停止中の場合は実行の再開 |

- ちなみに `kill PID`（デフォルト） では、TERMという、終了を指示するシグナルを送信します。
```zsh
# この2つのコマンドは同じ
kill 12360
kill -TERM 12360
```
それでは、killコマンドの流れを1つ見てみましょう。
- 例） バックグラウンドで実行しているsleepコマンドをkillコマンドで終了させる
![スクリーンショット 2023-08-04 10.04.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599480/79199919-b235-9832-77fa-16c88a133d92.png "sleepコマンドのプロセスを終了させる過程")

このように `kill PID` の入力でプロセスを終了させることができます。

- `sleep`コマンド：指定された秒数分、処理を遅らせるコマンドです。
- バックグラウンド：コンピュータ上で実行されているプログラムやタスクが、画面上に表示されずに裏側で動いている状態のことを言います。例えば、ゲームをしている最中に音楽を再生したり、ウェブブラウジングをしながらファイルのダウンロードを行うことがバックグラウンドでの活動です。

  Linuxでは、ターミナルでコマンドを実行する際に、そのコマンドが画面上で出力を表示せずに裏で実行されることがあります。これを「バックグラウンドで実行する」と言います。バックグラウンドで実行することで、他の作業をしている間にもプログラムを動かしたり、複数のタスクを同時に処理したりすることができます。

| コマンド | 説明 |
| :--- | :--- |
| `kill` | プロセスに対してシグナルを送り、プロセスを終了させるコマンドです。 |
| `kill PID` | 指定したプロセスIDにシグナルを送り、プロセスを終了させます。 |
| `kill -シグナル番号 PID ` | 指定したプロセスIDにをシグナル番号に該当するシグナルを送り、プロセスを終了させます。 |
| `kill -シグナル名 PID ` | 指定したプロセスIDにをシグナル名に該当するシグナルを送り、プロセスを終了させます。 |


# おわりに
Linuxは一つの要素にいろんな要素が絡んでいるため、ピンポイントで学ぶには難しく、特に初めて学ぶ方にとっては学習のハードルが高いと思います（私は学んでいて、そのように感じました）。

「そんな高いハードルが、ちょっぴりでも低くなるお手伝いができたらいいな」と思いながら初学者が知っておきたいLinuxのアレコレを初学者なりに綴ってみました。

ご覧くださり、ありがとうございました。