黒い画面入門

## 対象読者
未経験新人エンジニアとして入社したら、なにやら黒い画面を使うことになって困った人

## 黒い画面の正体
マウス操作が効かなければそいつは十中八九ターミナルと呼ばれるソフトです
macだと白い画面かもしれませんが、そいつもターミナルです
なぜエンジニアがそんな聞いたこともないような物を使っているのかと言うと、非常に便利だからです
ターミナルはざっくり言うと、CLI (コマンドラインインターフェース)を使うための端末のことを指します。
もっとざっくり言うと、コマンド入力するための端末です。
何のコマンドかと言うと、それはパソコンを操作するためのコマンドです。

## コマンドってなんだ
ターミナルに半角で `df` と打ってみましょう。するとなにやら英数字が出てきたはずです
`df` はパソコンのディスクの空き容量を表示するためのコマンドです。つまり、そこに表示されているのはパソコンのディスクの空き容量なのです
さらに、`df -h` と打ってみましょう。さっきより大分見やすくなったと思います。`-h` とは `df` コマンドのオプションです。エラーが出た人は、全て半角になっているか確認して再度試して見てください。

コマンドは、`コマンド -オプション` の形式で実行します

そしてコマンドは、実行することで用意されているプログラムが働き、OSを操作し情報を返却します

誰が用意したプログラムかと言うと、それはシェルが用意したプログラムです。（有志が作ったコマンドをインストールしてきて使うこともできますが、今は割愛します）

まとめると、
1. ターミナルソフトからコマンドを叩く
2. シェルがそれを受け取り、OSを操作する
3. OSがシェルに情報を返却する
4. ターミナルソフトに結果が表示される

コマンドを打った時の流れはこのようになっています
ちなみにシェルという命名は、OS を包み込む 殻 という意味でつけられました

## Linux
[こちら](https://www.atmarkit.co.jp/aig/03linux/gnu.html)の説明が秀逸
有志が作った無償公開されている OS のことです
UNIX の上位互換で、GPL（ジェネラルパブリックライセンス・非秘匿を旨としたライセンス）に基づいています
プログラムの世界ではこの Linux OS の一種である Ubunts や CentOS などがよく使われるうえ、mac も Linux の親戚の Unix をベースとしているため、コマンドでの操作が可能なのです
逆に言えば Windows は独自路線を突き進んだので、Linux 系のコマンドは専用のソフトウェアを入れないと使えませんでした

余談ですが Linux 系 OS ではフォルダのことをディレクトリと言います。意味合いはフォルダと同じです。

## コマンド入門
以下、基本的なコマンドです
<dl>
<dt>PWD</dt>
<dd>カレントディレクトリ(今ターミナル上であなたがいるディレクトリ)を表示するコマンド
使い方: `pwd`
</dd>
<dt>LS</dt>
<dd>ディレクトリ内のファイル一覧を表示する
使い方: `ls`</dd>
<dt>CD</dt>
<dd>カレントディレクトリを移動するコマンド
使い方：`cd 移動したいパス`</dd>
<dt>MKDIR</dt>
<dd>ディレクトリを作るコマンド
使い方: `mkdir 新規ディレクトリ名`</dd>
<dt>TOUCH</dt>
<dd>新しいファイルを作ったり、ファイルの更新日を更新するコマンド
使い方: `touch ファイル名`</dd>
<dt>CAT</dt>
<dd>ファイルの中身を表示するコマンド
使い方: `cat ファイル名`</dd>
<dt>LESS</dt>
<dd>ファイルを少しづつ表示するコマンド
使い方: `less ファイル名`</dd>
<dt>HEAD</dt>
<dd>ファイルの先頭数行を表示するコマンド
使い方: `head ファイル名`</dd>
<dt>TAIL</dt>
<dd>ファイルの末尾数行を表示するコマンド
使い方: `tail ファイル名`</dd>
<dt>CP</dt>
<dd>ファイルをコピーするコマンド
使い方: `cp コピーするファイル コピー後のファイル`</dd>
<dt>RM</dt>
<dd>ファイルを削除するコマンド
使い方: `rm 削除するファイル`</dd>
<dt>grep</dt>
<dd>ファイル中、あるいは標準出力の中から指定された文字列と一致する行を抽出するコマンド
使い方: `grep 抽出したい文字列 ファイル`</dd>
<dt>find</dt>
<dd>ファイルを検索するコマンド
使い方: `find . -name 検索したいファイル名`</dd>
</dl>

こうしてみると、マウス操作でできるようなことをコマンドで打っているだけですね
文字での操作になるので、カーソル特有のミスが少なくなったり繰り返し作業に強いのがメリットです

## パス
例えば `/home/var/` というディレクトリ構造が存在していて、あなたのカレントディレクトリが `/` だったとします
そこで `/home/var/` 配下に `index.html` というファイルを作るにはどうしたらいいでしょうか

やりかたは 2 通りあります。
1.

```
cd home/var
touch index.html

```

2.

```
touch home/var/index.html
```

これを見てわかる通り、ファイル操作はそのファイルがある場所に行って行うこともできますが、パスごと指定してあげることでカレントディレクトリを移動せずに行うことができます
これはファイルの削除やコピー、ファイルの編集や確認など全てのコマンドで有効です

### 特定の記号
特定の記号は、特定のパスを示します。以下にその例を載せます

| 記号 | 意味 |
|:-:|:-:|
| /  | ルート(最上階)ディレクトリ  |
| ~/  | ユーザのルートディレクトリ（ユーザがログインした時に最初に訪れるディレクトリ）  |
| .  |  現在のディレクトリ |
| ..  |  一つ上のディレクトリ |

## パイプ
パイプはコマンドの標準出力を別のコマンドの標準入力とできる機能です
例えば現在動いているプロセス一覧を表示する `ps aux` の中から、3000番ポートを使っているプロセスを見つけたい場合 `ps aux | grep 3000` などとすると当該のプロセスを見つけることができます

## vi(vim)
黒い画面を操作している時の強敵。それがvi(vim)です
敵というからには、乗り越えた暁には強力な仲間になってくれます

さて、vi は CLI 用のテキストエディタです
早速その使い方を見て見ましょう

`vi ファイル名`

これでファイルを開けます

### 挿入モードと通常モード
vi は挿入モードと通常モードに分かれています。これがややこしさの原因だと思う人もいます（主に私）
GUI のエディタのようにキーボードを打てば素直に出力してくれるのがこのモードです。コピペなども GUI のエディタのように cmd + c & cmd + v で行えます

そして通常モードですが、こちらはキーに割り当てられた機能を実行できるモードになります
例えば`yy`で一行コピー、`dd`で一行切り取り、`p` で貼り付けとなります

|  コマンド  |  効果  |
|:-:|:-:|
| yy | 一行コピー(ヤンク) |
| dd | 一行切り取り |
| p | ペースト |

#### まとめてコピー or まとめて切り取り
`数字yy or 数字dd` とすることで、まとめてコピーや切り取りを行うことができます。複数行コピーしていても、ペーストは `p` だけで大丈夫です

#### インサートモードと通常モードの切り替え
通常モードで `i` キーを押すことでインサートモードに切り替えることができます
逆にインサートモードから通常モードに切り替える時は esc キーです

| コマンド | 効果 |
|:-:|:-:|
|  i | インサートモード  |
| esc |  通常モードに切り替え、入力中のコマンドをキャンセル |

### 戻る と 進む
GUI エディタでよく使う戻ると進む機能も、もちろん vi にも同じ機能が付いています

| コマンド | 効果 |
|:-:|:-:|
|  u |  戻る |
|  control + r |  進む |

### 保存 と 終了
| コマンド | 効果 |
|:-:|:-:|
|  :w |  保存 |
|  :q |  終了 |
| :q! | 強制終了 |
|  :wq |  保存して終了 |

### 検索 と 置換
検索は通常モードで `/検索する文字` とすることで実行できます
検索結果が複数あった場合は `n` で下を検索、 `shift + n` で上を検索

置換は `:%s/検索する文字列/置換する文字列/` とすることで最初に見つかった一件を置換できます
全件置換は `:%s/検索する文字列/g` と、`g` フラグを末尾につけてあげれば全件置換となります

### 行ジャンプ
`:行数`　で指定の行までカーソルを移動することができます
もし行数を表示したかったら `:set number` とすることで行数を表示できます

## シェルスクリプト(追記)
シェルは直接ターミナルに入力して実行する他に、ファイルに記載して一気に実行することもできる

```
$ touch test.sh
$ echo '#!/bin/bash' > test.sh
$ echo 'echo hoge' >> test.sh
$ chmod a+x test.sh
$ ./test.sh
```

例えば上記のコマンドを上から順にターミナルに打ち込んで実行してみると、最後の `./test.sh` というシェルスクリプトを実行したところで hoge と返ってきます

上記のコマンドは
1. test.sh というシェルスクリプトのファイルを作る
2. echo コマンドで #!/bin/bashを test.sh に書き込む(> で上書き)
3. echo コマンドで 実行したいコマンドを、test.sh に追記する'(>> で追記)
4. test.sh の実行権を全てのユーザに付与する
5. test.sh を実行する

となっています

`#!/bin/bash` はシバンといい、シェルスクリプトで実行してほしいと依頼する一文です

| コマンド | 効果 |
|:-:|:-:|
|  echo |  標準入力を標準出力として返します。(渡された文字列をそのまま返します) |
|  chmod |  ファイルの権限を変更します。ファイルには 読み込み(read) 書き込み(write) 実行(execute) の三種類の権限が、 ユーザー(あなたのアカウント) グループ その他 の三種類のアカウントに設定できます |

### 引数
シェルスクリプトは引数を取ることができます
例えば入力した名前に挨拶を返すスクリプトは以下のようになります

```
#!/bin/sh
echo hello $1
```
このスクリプト(greeting.sh)を引数をつけて実行します

```
$ ./greeting.sh john
hello john
```

このように、シェルスクリプトは引数を取ることもできます
第一引数が `$1`, 第二引数が `$2`, 第三引数が `$3` となっています。ちなみに `$0` はファイル名です

### 変数
シェルスクリプトでは変数を使うこともできます
例として、与えられた引数を二乗して表示する `pow.sh` を以下に示します

```
#!/bin/bash
pow=$(($1*$1))
echo pow $1^2 = $pow
```

変数 `pow` に `$1 * $1` の値を代入し、それを echo で出力しています

ここで重要なことは三つあります
1. 代入式は前後にスペースを入れない
2. 式中の計算は `$(())` で囲む
3. 変数展開時は頭に `$` をつける

実行結果は以下のようになります

```
$ ./pow.sh 5
pow 5^2 = 25
```

### if 文
if 文は

```
if [条件]; then
  処理
else
  処理
fi
```

というように書きます。

条件については[こちら](https://qiita.com/toshihirock/items/461da0f60f975f6acb10)のページが非常にがわかりやすくまとめてくれています

使用例は以下の例となります

```
#!/bin/bash
if [ $1 -gt 0 ]; then
  echo $1 は正の値です
else
  echo $1 は正の値ではありません
fi
```

### for 文
for 文は以下のような構文になっています

```
for 変数 in 配列
do
  処理
done
```

実際に使ってみると以下のようになります

```
#!/bin/bash
arr="hello world"
for i in $arr
do
  echo $i
done
```

結果

```
$ ./positive.sh
hello
world
```