初学者向けLinux本３冊読んでDevOps Roadmap的にまとめてみた

# 動機

OSのコンセプト？やってること？はざっくり理解したので、つぎはLinuxの基本を勉強する。

- [DevOps Roadmap](https://roadmap.sh/devops)

![linuxforqiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3388832/c63b1a0f-08e3-e1d6-eb85-e289685934dd.png)


# 対象の初学者向けLinux本

- [ゼロからわかる　Linuxコマンド200本ノック―基礎知識と頻出コマンドを無理なく記憶に焼きつけよう！](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%82%8F%E3%81%8B%E3%82%8B-Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89200%E6%9C%AC%E3%83%8E%E3%83%83%E3%82%AF%E2%80%95%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98%E3%81%A8%E9%A0%BB%E5%87%BA%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E7%84%A1%E7%90%86%E3%81%AA%E3%81%8F%E8%A8%98%E6%86%B6%E3%81%AB%E7%84%BC%E3%81%8D%E3%81%A4%E3%81%91%E3%82%88%E3%81%86%EF%BC%81-%E3%81%B2%E3%82%89%E3%81%BE%E3%81%A4-%E3%81%97%E3%82%87%E3%81%86%E3%81%9F%E3%82%8D%E3%81%86/dp/429713425X)
- [ITエンジニア1年生のための まんがでわかるLinux コマンド＆シェルスクリプト基礎編](https://www.amazon.co.jp/IT%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A21%E5%B9%B4%E7%94%9F%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE-%E3%81%BE%E3%82%93%E3%81%8C%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8BLinux-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%EF%BC%86%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E5%9F%BA%E7%A4%8E%E7%B7%A8-Piro-ebook/dp/B09XM7PL4P/ref=sr_1_1?adgrpid=52005894183&dib=eyJ2IjoiMSJ9.RGJU81Tyn5lcdLK8K-ZLU45ZFQBAs0Hvl22eHYUm5KJVThUW44D1SAWoCDBhk50HnhY8994f7oWeJO_fH8Qrvq_CE0NxuCx4qARun9Ca1GDSG9QPA50GSVjspM2aB3SG637gKuVmaJqX5Svu1Ck_yQFztBQUrxx2KCzr4FBgsWg.uAwSWU4VG75DqugMJfGI-3Rc8dSz93D5_vBGJQLp1BU&dib_tag=se&gclid=Cj0KCQiA5-uuBhDzARIsAAa21T-oFlJLciK5_roJOaMXbWMQq6MSu2FW_nhEZ0-70X36SQNtlgsLEHQaAsgeEALw_wcB&hvadid=679023051961&hvdev=c&hvlocphy=1028853&hvnetw=g&hvqmt=e&hvrand=15585432765785812463&hvtargid=kwd-332421179416&hydadcr=27265_14738572&jp-ad-ap=0&keywords=%E3%81%BE%E3%82%93%E3%81%8C%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8Blinux&qid=1708849563&sr=8-1)
- [[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識](https://www.amazon.co.jp/%E8%A9%A6%E3%81%97%E3%81%A6%E7%90%86%E8%A7%A3-Linux%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF-%E5%AE%9F%E9%A8%93%E3%81%A8%E5%9B%B3%E8%A7%A3%E3%81%A7%E5%AD%A6%E3%81%B6OS%E3%81%A8%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E6%AD%A6%E5%86%85-%E8%A6%9A/dp/477419607X/ref=sr_1_2?adgrpid=58705730092&dib=eyJ2IjoiMSJ9.llypRfsWcwPC1E7A_s6M2ZTdhi-Zi3kr6IiFQVatww4Qq7CnXZt6wCw7vpMSiFHT-jvLxhTsyHwsCVX0q1HwLyh1eA8DZxU_TDarf9LX7_AI_x3uEcEChSZ-SN70EjTX6oyclTWRAo3WiMyEbUNbjIfe6E-0N59VuRRD9Qsvq_XLhX1_Xp4jPfY9htTHwAegQNuT-KMwSuR9jCJDhLgV0NqBKb3kzod7_i5c1TtWu4Wi4VsVU1D-0JKPvuC1H59Lgl17jiL6yb1Xfa8bwEr5ZJNh0o4PSM7xu30bjbrrJTM.w476oRm7pHqQSUULIUzldi3hOXF5v5mzdnuUmWAb_9c&dib_tag=se&gclid=Cj0KCQiA5-uuBhDzARIsAAa21T_zjQkTTLlldbEQMaI0t41LWmwEV_Aj8puxpIPzHLmVhsxTK-GluKoaAhDwEALw_wcB&hvadid=679074412040&hvdev=c&hvlocphy=1028853&hvnetw=g&hvqmt=e&hvrand=849133179472624843&hvtargid=kwd-409345415739&hydadcr=27268_14738581&jp-ad-ap=0&keywords=%E8%A9%A6%E3%81%97%E3%81%A6%E7%90%86%E8%A7%A3+linux%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF&qid=1708849622&sr=8-2)

個人的に、順番は上記の列挙順がおすすめ。

- 1冊目は初学者でもめちゃくちゃわかりやすく書いてくれている
- 2冊目は漫画なので読みやすいけど、好み分かれそう
- 3冊目は仕組みを分かりたい人向け（タイトル通り）なのでお好みで


# 目次

- [Linuxの基本的知識・概念など](#linuxの基本的知識概念など)
  - [Linux OSとは](#linux-osとは)
  - [カーネルモードとユーザーモード](#カーネルモードとユーザーモード)
  - [Linuxディストリビューション](#linuxディストリビューション)
  - [LinuxコマンドとCLIでのサーバー操作](#linuxコマンドとcliでのサーバー操作)
  - [パーミッションという考え方](#パーミッションという考え方)
  - [ジョブとプロセス](#ジョブとプロセス)
  - [メモリ管理](#メモリ管理)
  - [ファイルシステム](#ファイルシステム)
- [DevOps Roadmap的コマンド集](#devops-roadmap的コマンド集)
  - [Process Monitoring](#process-monitoring)
  - [Performance Monitoring](#performance-monitoring)
  - [Networking Tools](#networking-tools)
  - [Text Manipulation](#text-manipulation)
- [Vimの基本](#vimの基本)
  - [Vimとは](#vimとは)
  - [エディタについての補足](#エディタについての補足)
  - [Vimとモード](#vimとモード)
  - [Vimの公式チートシート](#vimの公式チートシート)
- [Bash scripting（シェルスクリプト）](#bash-scriptingシェルスクリプト)
  - [Bashスクリプトを作成して実行する](#bashスクリプトを作成して実行する)
  - [Bashスクリプトの基本](#bashスクリプトの基本)
  - [profile](#profile)
  - [シグナルの理解](#シグナルの理解)
  - [終了ステータス](#終了ステータス)
- [おわりに](#おわりに)

# Linuxの基本的知識・概念など
## Linux OSとは

Linuxと言われたらLinux OSかLinuxカーネルのこと。

そもそもOSとは、コンピュータを動作させるための土台となる基本的なソフトウェア群のことで、アプリケーションを動かすだけでなく、コンピュータを使うための基本的な機能を提供している。

https://qiita.com/_mi/items/e71ecf4b4db169165286

## カーネルモードとユーザーモード

世の中には無数のデバイスが存在するが、Linuxにおいては同じ種類のデバイスであれば同じインターフェースで実現できるようになっている。

そのインターフェースになっているのがデバイスドライバであり、OSではデバイスドライバがプロセス（各種プログラムの実行単位）とデバイスとを結んでいる（ハードウェア抽象化）

視点を変えれば、各プロセスからデバイスに直接アクセスできないようになっている。（直接アクセスできてしまうと非常に都合が悪い）

これを実現しているのがCPUの

- カーネルモード
- ユーザーモード

という２つのモードであり、プロセス実行時にはユーザーモード、デバイスドライバによるデバイス操作はカーネルモードで動作する。

![カーネルモードとユーザーモード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3388832/86bbde3a-e269-37ad-3f64-85ee3fe32dce.jpeg)


### Linuxカーネルとカーネルモード

Linux OSの中核となっているソフトウェアをカーネルと呼ぶ。

Linuxカーネルの主な役割は以下のようなもの。

- プロセス管理
- メモリ管理
- デバイス管理
- ファイルシステム

当然カーネル以外のソフトウェアもたくさん存在するので、 Linux OS = Linuxカーネル + その他のソフトウェア群 という等式が成り立つ。中核を担うカーネルはプログラムを実行する機能を担い、また、プログラム実行のためにCPUやメモリの管理もしている。

### ユーザーモード

一般的なアプリケーションやプロセスが実行されるモードであり、ユーザーモードのプロセスの処理からシステムコールを介してカーネルの処理を呼び出す。

プロセスは実行の中でシステムコール（カーネルへの処理依頼）をすることで以下のような操作が実現できる。

- プロセスの生成や削除
- メモリの確保や解放
- ネットワーク機能

ユーザーモードのプロセスは、これらの操作を要求するためにシステムコールを使用してカーネルに処理を依頼する、カーネルは要求を受け取り、適切な処理を実行してプロセスの要求に応える。このように、プロセスとカーネルの間のやりとりを制御することで、システムのセキュリティと安定性を確保している。

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

Linuxカーネルはオープンソースなので無料で利用でき、かつ高い安定性と信頼性がある。そのため、Linuxベースのオペレーティングシステムは他のOSと比較して低コストで利用できると言われている。

が、LinuxカーネルはOSの一部機能しか担っていない（Linux OS = Linuxカーネル + その他のソフトウェア群 だからね）ので、その他の機能はカーネル以外のソフトウェアを用意する必要がある

LinuxディストリビューションはLinuxカーネルとその他のソフトウェア群をパッケージングして、OSとしてすぐに使えるようにしたもの。

代表的なディストリビューションは２つ

- Red Hat系：CentOSなど（CentOSはサ終が決まっているが）
- Debian系：Ubuntuなど


## LinuxコマンドとCLIでのサーバー操作

- GUI：視覚的に操作可能
- CLI：コマンドライン（文字列の入力で操作）

CLIの操作に頑張って慣れるべき根拠は以下のようなイメージ。

- GUIは必ずしも必要じゃない
  - いつもPCで見ているマウスがあってウィンドウがあってアイコンがあって...みたいなデスクトップ環境と言うが、サーバーにおいてこのデスクトップ環境は必ずしも必要でない
  - むしろ、サーバー用の環境構築する際にはサーバーの処理能力を最大限活用するために最小構成でセットアップすることも多い
- なんだかんだ小回りの利くCLI
  - リモートでのサーバー管理やスクリプトの自動化など、柔軟かつ効率的な操作が可能
  - 操作方法の変更がほとんどない
  - 多くの環境、ディストリビューション共通で使える
- サーバにはLinux OSが使われていることも多い

なのでCLIの操作を覚えるのは、開発者としてはコスパがいい。


## パーミッションという考え方

パーミッションとは、複数のユーザーがコンピュータを操作しても安全な動作を保証するLinux OSの仕組みの１つであり、利用するユーザーに対してファイルやディレクトリへのアクセス権限（読み取り、書き込み、実行）を割り当てること。

パーミッションの仕組みによってLinux OSはフールプルーフ（人がミスをしようとしてもできないようにする工夫）な設計を実現している。

具体的な権限の確認や権限の変更などは以下記事参照

https://qiita.com/shisama/items/5f4c4fa768642aad9e06

で、権限が付与されていなくても操作できるコマンドが`sudo`コマンド。スーパーユーザー（あらゆる操作が可能なもっとも強い権限を持つユーザー）としてコマンドを実行するために使われる。

※ `sudo`コマンドで実行できるコマンドは、`/etc/sudoers`でユーザーごとに設定（システム管理者が編集）可能なので、いつでもどこでも`sudo`できちゃうわけではない


## ジョブとプロセス

### ジョブ

コンピュータに実行させる作業のまとまりのことを指す。特に、Linuxにおいては実行されているコマンドラインのことをジョブという。１つのジョブには１つ以上のプロセスが含まれている。

また、ジョブとプロセスは見え方の違いでもあって、

- ジョブ：シェル（ユーザー）側から見た処理の単位
- プロセス：カーネルから見た処理の単位

例えばコマンドラインをイメージすると、ユーザーからは１つのジョブに見えるけど、カーネルからしたらそれは複数のプロセス（プログラム）の集合だよね、みたいな違い。

![ジョブとプロセス.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3388832/63aab68e-97ea-d112-f3de-9eace23ed164.jpeg)


### プロセス

[カーネルモードとユーザーモード](#カーネルモードとユーザーモード) でチラッと書いてはいるけど、プロセスとは各種プログラムの実行単位のことで、カーネルで管理・制御される。具体的には、実行するプログラムがメモリに格納され、その格納された内容に従ってCPUがプログラムを実行する。このとき、メモリに格納されてCPUによって実行されるプログラムのことを「プロセス」と呼ぶ。

実行される各プロセスにはプロセスIDという「一意」の識別子が割り振られていて、同じプログラムを実行した場合でも、別のプロセスとして区別ができるようになっている。

Linuxはマルチユーザーシステムでありマルチタスクシステムでもあるため、 Linuxマシン内では常に複数のプログラムが実行されていて、同一のプログラムが別のユーザーによって同時に実行されることもある。

このような環境においては、プログラムの実行を適切に管理をしないと、ほかのユーザーによる意図しないプログラムの実行終了や、データがプログラム間で混ざっちゃう、などの危険がある。こういったトラブルを防ぐために、Linuxではプログラムの実行をプロセスという単位で管理しているのだ。すごいね。


## メモリ管理

Linuxはシステムに搭載されている全メモリを、カーネルのメモリ管理システムと呼ばれる機能によって管理している。メモリは各プロセスが使うのはもちろん、カーネル自身も使う。

### 単純なメモリの割り当て

カーネルがプロセスにメモリ割り当てを行うのは大きく分けて以下の２つのタイミング

- １. プロセス生成時
- ２. プロセス生成後、追加でメモリを割り当てるとき

まず、プロセス生成時の場合。プロセス生成にも生成の仕方が2種類ある

- 同じプログラムの処理を複数のプロセスに分ける場合（メモリのコピペ）
- まったく別のプログラムを生成する場合（メモリの上書き）

上記の２つの方法はメモリ割り当ての過程こそ違うが、新しいプロセスに対して一意のプロセスIDを割り当てて、OSがそのプロセスの管理とリソースの割り当てを行うのは同じ。

次に、プロセス生成後に追加で動的にメモリを割り当てる場合。この場合は、プロセスはカーネルに対してメモリ獲得用のシステムコールを発行することによってメモリ割り当ての要求を行う。カーネルはその要求に応じてプロセスにメモリを割り当てる。

上記のような（仮想記憶がない場合の）メモリ割り当ての単純な仕組みだと以下の3つの問題が発生する

- メモリの断片化（メモリが散らばることで、１つにまとめて使えない）
- 別用途のメモリにアクセスできてしまう（データの漏洩や破壊のリスク）
- マルチプロセスの扱いが困難（メモリの競合や相互干渉が発生する）

※ 詳しくは  [[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識](https://www.amazon.co.jp/%E8%A9%A6%E3%81%97%E3%81%A6%E7%90%86%E8%A7%A3-Linux%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF-%E5%AE%9F%E9%A8%93%E3%81%A8%E5%9B%B3%E8%A7%A3%E3%81%A7%E5%AD%A6%E3%81%B6OS%E3%81%A8%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E6%AD%A6%E5%86%85-%E8%A6%9A/dp/477419607X/ref=sr_1_2?adgrpid=58705730092&dib=eyJ2IjoiMSJ9.llypRfsWcwPC1E7A_s6M2ZTdhi-Zi3kr6IiFQVatww4Qq7CnXZt6wCw7vpMSiFHT-jvLxhTsyHwsCVX0q1HwLyh1eA8DZxU_TDarf9LX7_AI_x3uEcEChSZ-SN70EjTX6oyclTWRAo3WiMyEbUNbjIfe6E-0N59VuRRD9Qsvq_XLhX1_Xp4jPfY9htTHwAegQNuT-KMwSuR9jCJDhLgV0NqBKb3kzod7_i5c1TtWu4Wi4VsVU1D-0JKPvuC1H59Lgl17jiL6yb1Xfa8bwEr5ZJNh0o4PSM7xu30bjbrrJTM.w476oRm7pHqQSUULIUzldi3hOXF5v5mzdnuUmWAb_9c&dib_tag=se&gclid=Cj0KCQiA5-uuBhDzARIsAAa21T_zjQkTTLlldbEQMaI0t41LWmwEV_Aj8puxpIPzHLmVhsxTK-GluKoaAhDwEALw_wcB&hvadid=679074412040&hvdev=c&hvlocphy=1028853&hvnetw=g&hvqmt=e&hvrand=849133179472624843&hvtargid=kwd-409345415739&hydadcr=27268_14738581&jp-ad-ap=0&keywords=%E8%A9%A6%E3%81%97%E3%81%A6%E7%90%86%E8%A7%A3+linux%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF&qid=1708849622&sr=8-2) 読んでください。


### メモリの仮想化（仮想記憶）

上記の3つの問題は仮想記憶によって解決される。仮想記憶は、物理的なメモリ以上のメモリ空間をプロセスに提供し、プロセスが必要なだけのメモリを利用できるようにする技術。

プロセス、仮想のメモリ、物理のメモリの登場人物をイメージすると分かりやすい。プロセスから見えるメモリのアドレスを仮想メモリ、仮想メモリに紐づいているのが散らばった物理メモリ。つまりシステムに搭載されている物理メモリにプロセスから直接アクセスさせるのではなく、仮想アドレスというアドレス（メモリの特定の位置を特定するための識別子）を用いて間接的にアクセスさせる方法がメモリの仮想化、仮想記憶というわけ。

仮想記憶を使うと、仮想記憶がない場合の3つの問題が解決できる。

- メモリの断片化（散らばったメモリがに１つにまとまっているように見せられる）
- 別用途のメモリにアクセスできてしまう（独立した仮想アドレス空間により他プロセスのメモリにアクセス不可）
- マルチプロセスの扱いが困難（仮想アドレス空間はプロセスごとに存在するので他と干渉しない）

かがくのちからってすげー!

![メモリの仮想化.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3388832/47c98645-4687-06c1-3a9c-cb19d6bbba88.jpeg)


## ファイルシステム

Linuxでは通常、直接ストレージデバイスにアクセスせず、ファイルシステムを通じてデータにアクセスする。

### 一般的なファイルシステムの概要

ストレージデバイスの機能はデータを保持するための物理的な場所に対して所定のサイズの読み書きを行うことだけ。なのでファイルシステムがない場合は、データの保存場所を自分で指定し、保存したデータの場所、サイズ、意味を覚えておく必要がある。複数のデータを保存する場合はめちゃくちゃ大変で、それぞれのデータについての自己管理に加えて空き容量の把握が必要になってくる、めっちゃつらい。

ファイルシステムはこのような煩雑な処理を回避するための機能で、データの場所や空き容量を管理し、データの保存やアクセスを容易にする。なので、ユーザー（から依頼を受けたプロセス）がファイル読み出しのシステムコールをすれば、該当するデータを見つけてユーザーに渡してくれるというわけ。

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

ファイルをカテゴリ別に整理できるよう、ディレクトリというファイルを格納するための特殊なファイルが存在する。この仕組みによってLinuxのファイルシステムはツリー構造をしている。

ディストリビューションによって多少の違いはあるものの、Linuxマシンのルートディレクトリ内の主なディレクトリは以下のようになっている。

| ディレクトリ名 | 説明 |
| :--: | :--: |
| `/bin` | 一般ユーザー向けのコマンド実行ファイル（**bin**ary file） |
| `/boot` | 起動（**boot**）に関するファイル |
| `/dev` | デバイス（**dev**ice）ファイル |
| `/etc` | システムの設定ファイル（**et c**etera） |
| `/home` | ホーム（**home**）ディレクトリ |
| `/lib` | コマンドが利用するライブラリ（**lib**rary）のファイル |
| `/proc` | プロセス（**proc**ess）やカーネルの状態に関する情報 |
| `/root` | **root**ユーザーのホームディレクトリ |
| `/sbin` | システム管理用の実行ファイル（**s**ystem **bin**ary file） |
| `/tmp` | 一時（**t**e**mp**orary）ファイル |
| `/usr` | アプリケーションとそれに付随するファイル |
| `/var` | ログなどの可変ファイル（**var**iable） |


### Linuxファイルシステムの補足

Linuxは複数のファイルシステムを扱える（ext3、XFS、ZFSなど）が、それぞれストレージデバイスのデータ構造、それを処理するためのプログラムが異なっている。（それゆえに扱えるファイルのサイズや個々の処理速度も違ってくる）

ただし、どのファイルシステムであっても、ユーザーは統一的なインタフェースであるシステムコールを使用してファイルの作成、削除、開く、閉じる、データの読み書きなどを行うことができる。


# DevOps Roadmap的コマンド集

コマンド集はいろんなところにいいまとめ記事があるけど、Roadmap上に抽出されてたコマンドくらいはアウトプットしておく。

# Process Monitoring

プロセスを監視しよう！

| **コマンド** | **説明** |
| :--: | :--: |
| `ps` | 現在実行中のプロセスのスナップショットを表示する |
| `top` | CPUやメモリの使用状況を確認 |
| `htop` | 直観的でインタラクティブなプロセスモニタリングビューワー |
| `atop` | 高度なシステムパフォーマンス監視 |
| `lsof` | 開いているファイルの一覧を表示する |

# Performance Monitoring

パフォーマンスを監視しよう！

| **コマンド** | **説明** |
| :--: | :--: |
| `nmon` | リアルタイムなシステムパフォーマンスを収集し表示する |
| `iostat` | CPUの使用率とI/Oデバイスの使用状況を表示する |
| `vmstat` | メモリやCPU、ディスクI/Oの統計情報を表示する |
| `sar` | システムのパフォーマンス統計データを定期的に収集し、表示する |

# Networking Tools

ネットワーキングのトラシューしよう！

| **コマンド** | **説明** |
| :--: | :--: |
| `traceroute` | ネットワーク経路を特定するためにパケットの経路を追跡する |
| `ping` | ホストにパケットの送信・応答の受信でネットワークの疎通確認やサーバの死活監視をする |
| `mtr` | ネットワーク経路の追跡と同時に、ホストまでの遅延やパケットロスの統計情報を提供する |
| `nmap` | 目的のホストへのポートスキャンによりネットワーク調査およびセキュリティ監査を行うための情報を提供する |
| `netstat` | ホストのネットワーク接続状態やソケット・インターフェイスごとのネットワーク統計などを表示する |
| `ufw` | UbuntuなどのLinuxディストリビューションで使用されるファイアウォールの設定ツール |
| `firewalld`[^firewalld] | CentOSやFedoraなどのLinuxディストリビューションで使用されるファイアウォールの設定ツール |
| `iptables` | Linuxで使用されるファイアウォールの設定を構成・管理する |
| `nft` | `iptables` の後継で、`nftables` ユーティリティーを使用してファイアウォールを設定する |
| `tcpdump` | ネットワーク通信の生のデータをキャプチャし、その結果を出力してくれるキャプチャツール |
| `dig` | DNS(Domain Name System)サーバーにクエリを実行して、ドメインの情報を取得する |
| `scp` | ネットワーク経由でファイルを安全に転送するために使用するSSHツール |

[^firewalld]: `firewalld`はLinuxのファイアウォール管理システムの名前で、それ自体はコマンドではない。firewalldを操作するためには、`firewall-cmd`コマンドを使用する。

# Text Manipulation

テキストいじろう！

| **コマンド** | **説明** |
| :--: | :--: |
| `awk` | 特定のパターンに一致する 列 を検索・抽出する |
| `grep` | 特定のパターンに一致する 行 を検索・抽出する |
| `sed` | **S**tream **ED**itorを使って、主に文字列の置換に使われる |
| `sort` | 昇順や降順、数値順にソートする |
| `cut` | 指定されたカラムやフィールドを切り出す |
| `uniq` | 連続する重複した行を1つにまとめ、一意の行のみを表示する |
| `cat` | ファイルの内容を連結して表示するか、新しいファイルを作成する |
| `echo` | 引数や変数の内容を表示する |
| `fmt` | 指定された幅に整形し、読みやすい形式にする |
| `tr` | 文字を変換したり削除したりする |
| `nl` | 行に行番号を付けて表示する |
| `wc` | 行数や単語数、バイト数などをカウントする |

# Vimの基本
### Vimとは

Linuxディストリビューションでよく使われるCLIベースのテキストエディタ。Vimはキーボードショートカットとコマンドを使ってテキストファイルを編集することができるが、GUIのテキストエディタと比べると直観的でない操作性になっているので基本を知っておかないと全然使えない...。でも使えたらそれだけでかっこいい。

### エディタについての補足

- スクリーンエディタ：画面上で対話的に編集する（vimはこれ）
- ストリームエディタ：コマンドラインで事前に指定された指示に従い編集や出力する（sedコマンドがこれ）
- ラインエディタ：１行ずつ対話的に編集できる（スクリーンエディタとストリームエディタの中間みたいなイメージ）

### Vimとモード

Vimには以下の4つの主要なモードがある

| **モード** | **概要** | **できること** |
| :--: | :--: | :--: |
| ノーマル | Vimの起動時の<br>デフォルトモード | 各モードへの切り替え、ヤンク、プット、削除など |
| コマンドライン | コマンド入力 | ファイル操作や検索・置換などのコマンド利用 |
| インサート | 挿入・編集 | 文字の直接入力 |
| ビジュアル | 選択 | 範囲選択、選択範囲のヤンク、削除など |

ほかにもいくつか補助的なモードがある。
- インタラクティブモード
- オペレーターモード
- セレクションモード

VimのもとになっているViはPCがなかった時代にテンキーやカーソルキー、マウスがない環境向けに作られたもの。ゆえに複数のモードが存在していて、１つのキーが複数の役割をこなせるよう設計されている。

Vimでの遊び方は他の人がたくさんいい記事書いているので、いろいろ探してみてください。

https://qiita.com/JpnLavender/items/fabcc79b4ab0d52e1f6d

### Vimの公式チートシート

http://vim.rtorr.com/lang/ja


# Bash scripting（シェルスクリプト）

シェルスクリプトの実体は単純なテキストファイルで、中にはコマンドの実行手順が書かれている。シェルのコマンドや機能を使用してタスクを自動化するために使用される。

一方、Bashスクリプトは `Unix` / `Linux` システムで広く使用されている特定の種類のシェルのことで、Bash（Bourne Again SHell）というシェルの拡張版を使用して記述されたシェルスクリプトのことを指す。

## Bashスクリプトを作成して実行する

bash スクリプトの拡張子は基本的には `.sh` だけど、なくても動く。

~~~bash:hoge.sh
#!/bin/bash

echo "これでもう完成"
~~~

シバン（Shebang）はシェルスクリプトの先頭に書かれる特殊な行で、スクリプトを実行する際に使用するシェルのパスを指定するためのもの。Bashスクリプトの場合は`/bin/bash`と書いてBashシェルのパスを指定している。（環境によってBashのインストール場所が異なる場合もあるので注意）

シバン行の目的は、スクリプトを実行する際にシェルを自動的に特定することで、シバン行がない場合は実行するシェルはデフォルトのシェルになる。（`#!`に続けてプログラムのフルパスを書いておくと、スクリプトを実行するプログラムをOSが自動的に切り替えてくれる！）

ちなみによく使われるシェルとスクリプト言語は `bash`/ `zsh` / `perl` / `ruby` / `python` / `node` など（らしい）



## Bashスクリプトの基本
### コメントアウト

~~~bash:fuga.sh
# これでコメントアウトできる
~~~

### Bash の変数とデータ型

- 変数を使用すると
  - データを保存できる
  - スクリプト全体でデータの読み取り、アクセス、操作を行うことができる
- Bash にはデータ型がない
  - Bash では、変数は数値、個々の文字、または文字列を格納できる

Bash では、以下のような方法で変数を使用・設定できる

~~~bash:fuga.sh
# 値の直接の割り当て
key=hoge

# 変数へのアクセス（hogeが出力される）
echo $key　

# 変数の値を別の変数に代入（hogeが出力される）
new_key=$key
echo $new_key　
~~~

### コマンドラインで引数を渡す

Bashスクリプト
~~~bash:konnitiha.sh
#!/bin/bash

# コマンドライン引数から名前を受け取る
name=$1

# パーソナライズされた挨拶を出力する
echo "こんにちは、$nameさん！"
~~~

Bashスクリプトの実行
~~~
$ bash konnitiha.sh _mi
~~~

出力
~~~
こんにちは、_miさん！
~~~

### 出力の方法
~~~bash:koko.sh
#!/bin/bash

# ターミナルへの出力
echo "Hello, World!"

# ファイルへの出力（上書きになるので注意）
echo "hogehoge" > output.txt

# ファイルへの追加（ファイルの最後に追加）
echo "fugafuga" >> output.txt

# 出力のリダイレクト（結果がそのままファイルへ）
ls > files.txt
~~~

### できること

- 条件文 (if/else) ※ ３つ以上に分岐する場合`if-elif-else`になるので注意！`elif`！
- for / Whileループ
- case句
- スケジューリング実行（`cron`の利用）
- デバッグ
- エラーハンドリング（`if [ $? != 0 ] then exit; fi`はとりあえず書くおまじない）

## profile

Bashにはユーザーの設定や環境変数などを記述するための特定のファイルがある。

- `.bash_profile` : 
  - ログインシェル（システムログイン時に自動的に起動されるシェル）が起動されるときに読み込まれる
  - 環境変数とか設定しておくといい
- `.bashrc` : 
  - インタラクティブシェルが起動されるときに読み込まれる
  - エイリアス / シェル関数 / コマンドラインの補完を設定しておくといい

この辺はプロセスやサブシェルの理解があると頭に入りやすいと思う。

https://qiita.com/tockey/items/021b804b9957fe65e093

## シグナルの理解

シグナルとは、OSがプロセスに対して送信する信号（signal）のことで、シグナルを送ることでプロセスを操作できる。

シグナルを送信するには、kill コマンドを使用することが一般的。kill コマンドは、指定したプロセスID（PID）に対して特定のシグナルを送信することができる。

~~~
$ kill [シグナル名 / 番号] PID
~~~

シグナルの種類としてはプロセスの終了や停止、強制終了するものなどがあるが、`kill -l` で使用可能なシグナル一覧が確認できる。

~~~
$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
... // 以下略
~~~

ちなみに、ジョブを停止するための `Ctrl + z` とかジョブ終了する `Ctrl + c` を入力したときも、ジョブに含まれているプロセスに対してシグナルが送信されている。

https://qiita.com/ine1127/items/5523b1b674492f14532a


## 終了ステータス

Bashの終了ステータスはBashシェルが実行されたコマンドやスクリプトの終了時に生成される数値のこと。

スクリプト内で実行される他のシェルコマンドやプログラムが実行されると、終了ステータスは `$?` に格納され、以降の処理で参照することができる。

- 終了ステータス 0 は正常終了、1 以上は通常エラーを示す
- 終了ステータスは0から255までの範囲と決まっている
- あくまで直前のコマンドの終了ステータスを返すことに注意

~~~bash:boo.sh
#!/bin/bash

$ command # コマンドを実行（エラーが発生するとする）
$ echo $? # 直前のコマンドはエラーなので 1 を表示
$ echo $? # 直前のechoコマンドは正常終了なので 0 を表示
~~~


# おわりに

アウトプットして理解は深まったけど、記事としては内容が浅すぎて誰の役にも立たなそうなものが出来あがって泣いた。

私が読んだ書籍の中にはもっと詳しくわかりやすく多くの記述があるので、初学者は読んでみることをオススメします。

業務でやってることへの理解が急激に深まったので、たのしくなったよ。