Terminalを使いこなせるようになろう

目次

* 初めに
  * なぜターミナルを使う必要があるのか
  * CLIには学習がつきもの
* 本編
  * 目的・目標
  * 基本コマンド
  * ターミナルをカスタマイズ
  * 用語説明
  * 環境変数やPathの概念を体得する
  * おまけ

# 初めに

## なぜターミナルを使う必要があるのか


### ①CLI(CUI)の方がGUIより操作が速い
  * 例えばDesktop/development/railsのアプリディレクトリを開きたいと思った時、Finderで探すと、「Desktop」を探し、その中から「development」を探し、さらに「rails」を探して最後にそのアプリの名前を探さなければたどり着けない。探すと言うのは地味に時間と脳のメモリを使う行為である。
 
  * CLIだとキーボードの配置を一度覚えれば目を瞑っても操作できる。それに対して、GUIでマウスを動かして操作しようとすると、手を大きく動かしたり、目で確認したりして、操作を行わなくてはならない。

例えばGitの操作を考えてみよう。CLIだとブランチの移動からpull requestまで以下のコマンドで済ませることができる。

```terminal:terminal
$ git checkout -b development
$ git add -A
$ git commit -m "コミット"
$ git push -u origin development
$ hub pull-request -b master -m "プルリクだよ"
```
そして、通常は、aliasと言うものを作成し、このような長いコマンドをうつ必要性すらない。

```terminal:(例)
$ gcb development
$ gaa; gcm "コミット"; gpu development;
$ hp -b master -m "プルリクだよ"
```
Source Treeとgithubのブラウザ上での操作を思い出してみたらそれがどれだけの手の動きを意味し、URLを思い出したりとかして時間がかかるか理解しやすいだろう。

### ②言葉による共有の方が確実だから

例えばリモートでGitについて教えることになったとしよう。

GUIだと「この辺にあるaddボタンを押して、あの辺にあるテキストボックスにコミットメッセージを書いて、その辺にあるcommitボタンを押して」と説明しなければならない。

それに対してCLIなら,

```terminal:terminal
$ git add -A
$ git commit -m "メッセ" 
```
と操作を送るだけで成立し、さらに指示の意味を間違える可能性が低い。

### ③低レイヤー技術ほど、流行がない

RailsやReactといったフレームワークやライブラリはその時代の流行や期待されるニーズによって流行り廃りがあり10年後には役に立たない知識になっている可能性がある。それに対して、shellやOSといったコンピュータの基幹系に近い技術は数十年単位で変わることがない。身につけておいて損はないのだ。

## CLIには暗記がつきもの

CLIは学習コストが高くこんなにも便利なのになかなか普及しにくいのである。しかしエンジニアとして人を教える立場ならほんの少しの学習で大きなリターンになるのでぜひやるべきである。そして何よりこの程度の障壁は乗り越えられなければならない。

# 本編

## 目的・目標
* ターミナルで使える基本コマンドをmasterする
* カスタマイズできるようになる。


## 基本コマンド

とはいえ、基本コマンドはネットを探せばいくらでもヒットするし、ここでもう一回まとめるのも二度手間なので、参考リンクを載せておく。

* <a href="https://qiita.com/ryouzi/items/f9dee1540a04a0bfb9a3" target="_blank">Macのターミナルコマンド一覧（基本編）</a>


## 用語説明

* ターミナル
ターミナルとは「ユーザがコンピュータへ入出力する際に利用する専用のハードウェア」のことを指す。しかし現在、ハードウェアとしてのターミナルをが使われることはほぼなく、その代わりに、物理的なターミナルをソフトウェアによて実装したターミナルエミュレータが使われている。(つまりMacのアプリケーションであるターミナル(やiTerm2)は正確にはターミナルエミュレータと呼ぶ方が正しい。)

* Shell
ユーザーインタフェースであり、入力された文字列を受け取り、解釈してOS(カーネル)に命令を実行したり、受け取った処理結果を文字列に変換して出力したりする。

* OS(カーネル)
Shellで解釈された命令を実際に処理し、処理結果をかえす。



イメージ

<img width="724" alt="ターミナル説明.png" src="https://qiita-image-store.s3.amazonaws.com/0/220907/c5dbfb38-b119-d8f8-1cc7-49fb939a7f15.png">


### つまり

shellを自分の使いやすいようにカスタマイズしてやればもっと快適なエンジニアライフが送れる。

## シェルのカスタマイズ

用語説明で話したようにシェルは実際の処理とは切り離されているので、自分好みにカスタマイズすることができる。
そこで、インストールも簡単で割と便利な機能も含んでいる「oh my zsh」を紹介しておく。

<a href="https://github.com/robbyrussell/oh-my-zsh" target="_blank">oh my zsh インストール方法</a>

## 環境変数やPathの概念を体得する

実際にshellスクリプトを一緒に書いてみましょう。カレンダーと今日の気分を出力するだけのプログラムです。

```sh:kyounokibunn
#!/bin/bash
cal
echo "今日の気分は$1です。"
```

実行権限を付与しパスを通す

```terminal:terminal
$ chmod a+x kyounokibunn
$ PATH=$PATH:/{スクリプトを作成したディレクトリの絶対Path}
$ export
$ kyounokibunn
```

##### 参考:シェルの実行順序
1. alias
2. 関数
3. Bash等シェルのbuiltinコマンド(echoなど)
4. PATHが通った所に置いてある実行ファイル(複数ある場合はPATHの中で先に指定してる場所のものが優先)

## おまけ

### Z
zとはcdによる移動履歴をみて移動場所を補完することでディレクトリ移動を楽にしてくれるツール。cdでの移動が`~/.z`に保存され、そこにあるディレクトリには一気に移動できるようになる。

* https://github.com/rupa/z



使い方

```terminal:terminal
$ z [移動したいディレクトリ名の部分名]
```


インストール

```terminal:terminal
$ brew install z
```

`~/.zshrc`に追加

```terminal:~/.zshrc
# z
. `brew --prefix`/etc/profile.d/z.sh
```