# 知識習得コンテンツ CLI編
## CLI
- **☆コマンド操作で何ができるかということに対する理解**
- コマンド操作で実践できること
↓
[3/15 追加]
Git前に『ツールの使い方』的な感じで別枠にする?
先出しのメリデメを確認する
(末尾に追加)
### 共通
- 基本形としては、`コマンド オプション ファイル名`になります。
- オプションを追加するには`コマンド -〇`(〇には特定の英数字が入ります、例:`ls -l`)と入力します。
- 〇に2文字以上入れることで、複数のオプションを組み合わせることもできます。(例:`ls -la`)
- `コマンド --オプション名`(例:`ruby --version`)とハイフンを2個用いる書き方もあります。
- オプション、ファイル名はそれぞれ省略できる場合もあります。
- `コマンド --help`(例:`ls --help`)を実行すると、そのコマンドにどのようなオプションが追加できるか確認できます。
### ワイルドカード
ファイル名に`*`が使用できます。ワイルドカードと呼ばれるものの1つです。
`*`は任意の0文字以上の文字列を表し、それ単体だけでなく他の文字列と組み合わせて使うこともできます。
##### 例
例えば以下のようなファイル構成を考え、作業ディレクトリはtestとします。
```
test
- sam.html
- sample.txt
- sample.rb
- sample2.rb
- z.rb
```
`ls`コマンドでは、後ろにファイル名を付けることで合致するファイルだけに絞ることができます。
まずは以下を実行すると、「0文字以上」のファイルを検索するので、`ls`だけで実行した場合と同じ結果になります。
```
$ ls *
sam.html sample.txt sample.rb sample2.rb z.rb
```
次に以下を実行すると、「『samp』+0文字以上」のファイルを検索します。
sam.htmlとz.rbはこの条件に合致しないため、表示されません。
```
$ ls samp*
sample.txt sample.rb sample2.rb
```
また、`*`の後ろに付けることもできます。以下では拡張子が「.rb」のファイルを検索しています。
```
$ ls *.rb
sample.rb sample2.rb z.rb
```
`ls`コマンドを例にとりましたが、もちろん他のコマンドでも使用可能です。
### command not found
command not foundとは「コマンドが見つかりません」という意味です。
この文章が表示される原因としては以下の(1)~(3)が考えられます。
#### (1) コマンドのタイプミス
例えば`pwd`は正しいコマンドですが、
これを`pwb`,`qwd`などスペルミスをしてしまうとcommand not foundが発生します。
まずは正しいスペルかどうか、カリキュラムやネット検索で確認しましょう。
#### (2) 文頭に不要な文字が入っている
カリキュラムではターミナル表記として、以下のように文頭に`$`が表示されています。
```
$ ls
```
しかし、この`$`も含めて入力してしまうと、`$`に対応するコマンドはありませんので、command not foundが発生します。
```
$ $ ls
bash: $: command not found
```
実行する場合は`$`を抜いて実行しましょう。
#### (3) 必要なライブラリがインストールされていない
カリキュラム【Gitを学ぼう】0章ではMac、Windowsそれぞれの手順に従ってGitをインストールしました。
このようにインストールされているものは使えますが、逆に言えばインストールされていないものは使用できません。
例えばAI教養コースで「JupyterLab」というものを用いますが、これを利用するためにはインストールが必要です。
実際にターミナルやコマンドプロンプト、Cloud9で以下コマンドを実行するとcommand not foundが発生します。
```
$ jupyter --version
bash: jupyter: command not found
```
※もしインストールされていた場合はバージョンが表示されます。
### よく使われるオプション
利用可能なオプションはコマンドそれぞれで異なりますが、
ある程度共通して用いられるものもあります。
ここではその一例を紹介します。
#### -a / --all
隠しファイルも対象にする。
例:`ls -a`
#### -f / --force
強制的にコマンドを実行する。
※`grep`,`tail`など、「-f」=「--force」**ではない**コマンドもあります。
##### !注意!
実行しても問題がないことをきちんと確認してから使用しましょう。
例えば以下コマンドを実行すると、現在のディレクトリの中身が全て問答無用で削除されてしまいます。
```
$ rm -rf *
# 現在のディレクトリの中身を強制削除
```
#### -i
確認ステップを追加する。
##### 例
以下のように「-i」を付けて実行すると、確認メッセージが表示され、処理が止まります。
```
$ rm -i index.html
rm: remove regular file ‘index.html’?
```
この状態で「yes」または「y」を入力し、Enterを押すと削除されます。
それ以外の文字を入力すると処理がキャンセルされ、削除されません。
#### -r
ディレクトリも対象にする。
このオプションを付けずに実行すると、以下のようなエラーが表示されることがあります。
```
$ rm ディレクトリ名
rm: cannot remove ‘ディレクトリ名’: Is a directory
```
※`ls -r`の場合は逆順(reverse)で表示されます。
#### -R
ディレクトリに対し再帰的に実行する。
##### 例
例えば以下のようなファイル構成を考え、作業ディレクトリはtestとします。
(※拡張子は省略していますが、x,yはここではディレクトリではないとします。)
```
test
- dir1
- x1
- x2
- x3
- dir2
- y1
- y2
```
まず、以下のように何もオプションを付けずに実行すると、「dir1 dir2」のみ表示されます。
```
$ ls
dir1 dir2
```
次に、「-R」オプションを付けて実行すると以下のようになります。
```
$ ls -R
.:
dir1 dir2
./dir1:
x1 x2 x3
./dir2:
y1 y2
```
dir1, dir2に対してもlsコマンドが実行されたような結果になります。
lsコマンドは「ディレクトリの中身を一つ一つ表示する」コマンドになりますが、
「-R」オプションを付けることで、中身にディレクトリが含まれていたら、それに対しても処理を行い、そのまた中身にディレクトリが含まれていたら...といった動きになります。
マトリョーシカと同じイメージ、といえば分かりやすいでしょうか。
これが「再帰的」が表す意味です。
#### -v / --version
バージョンを確認する。
例:`ruby -v`
※`cp`, `mv`, `rm`のように、「-v」=「--version」**ではない**コマンドもあります。
### その他所感
#### (1) AWS3章の扱い
AWS > 3章【EC2でLinuxを学ぼう】にもほぼ同じような(※厳密には若干発展的)内容があるが、新コンテンツ側で内容を包括してこちら削除という手もアリ?
→ 被りはCLIに移動で。確認問題など、実践箇所については吸収合併の感じ
#### (2) historyについて
`history | grep ○○`(過去のコマンド履歴検索)はどこかで紹介したいが、
Windowsが`history`非対応であることは念頭におくべき。
現行のカリキュラムの`history`の箇所では、わざとWindowsの画像を載せていない。
AWS3章の方はEC2で行っているので両方可能で問題なし。
```
(走り書き)
Windowsの方は、【Rubyを学ぼう】以降で利用するCloud9や、
【AWSを学ぼう】以降で利用するEC2から利用可能です。
このようなコマンドがある、ということだけ覚えておいてください。
```
#### (2.5) historyについて - Windows
(2)を書いていて気づいたので追記。
Windowsでもhistoryコマンド相当のものがありました。
以下コマンドを実行すると、コマンドの履歴が出力されます。
```
$ doskey /history
# 省略形
$ doskey /h
```
また、1個以上の履歴がある状態で`F7`を押すと履歴ボードが表示されます。
`↑`,`↓`で履歴の移動ができ、Enterキーを押すと選択された履歴のコマンドが実行されます。
実行せずに終了するには`esc`キーを押します。
#### (3) -Rの説明について
`-R`(再帰的)の説明はアレでいいのかな...不安
#### (4) 下記文言の確認
迷って上にしたが、以下2択のどちらが分かりやすいか
- 「-v」=「--version」**ではない**
- 「-v」≠「--version」である
#### (5) 並列「|」の説明
### 先出しの場合のメリデメ
#### メリット
- 最初にCLIについての知識を習得することで、直近のGitなどその後の学習が円滑に進めやすくなる。
- 現状では最初にCLIを用いるのがXcodeのインストール/GitHubの秘密鍵作成時なので、よくわからないまま進めている方が多いのではないでしょうか。 ※推測
- 先出しすることで余計に初手躓くようになる、ということは無いと思います。
- 別章にすることで、「CLIに困ったときはこのカリキュラム」とより直感的に分かりやすくなる
- 現状はGit > CLIというステップであるため。
#### デメリット
- 実際に今後使用していくイメージが付きづらそう?
- 書きながらも既に疑問点。メリットで記載した通り、現状よくわからないまま進めている人の方が多いと推測される。
- 「初手に学習するコンテンツである」をより意識し、初学者が躓きづらい構成を考える必要がある。
### 章立て
別スプシ参照
「ツールの使い方を学ぼう」を大章として作成
3,4章は学ぶのみ。5章で実践。
## 既存コンテンツの確認
### Git > CLIを学ぼう
#### よく使うコマンド
- pwd
- Windowsは「/c」から始まるため、分けて表示。
- CLIを起動したときに最初にいるディレクトリを「ホームディレクトリ」と呼び、`~`(チルダ)で表されます。
- タイポでcommand not foundの説明
- ls
- カレントディレクトリにあるファイルを表示します。
- `$ ls -a`で隠しファイルも表示される
- たぶん隠しファイルの例があった方が分かりやすい
- `$ ls ディレクトリのパス`で対象ディレクトリの内容も確認可能。
- 演習(1)
- `$ ls ~/Desktop`
- Windowsでエラーが起こる場合:OneDriveで同期されているため、ホームディレクトリにDesktopフォルダが無い。`$ ls ~/OneDrive/デスクトップ`
- ``$ ls -a ~/`` でホームディレクトリの隠しファイルを表示
- cd
- `$ cd Desktop`
- Desktopフォルダ内にDesktopフォルダはないので、移動後に再度`$ cd Desktop`はできない。no such file or directoryの画像。
- lsコマンドでカレントディレクトリの中を確認してからcdコマンドを利用するなどするとミスが減ります。
- 演習(2)
- `$ cd ~/Downloads`
- mkdir
- `$ mkdir new_folder`
- rm
- `$ rm new_folder`では削除できないことを確認
- `-r`,`-f`オプションの説明
- 演習(3)
- `$ mkdir dirA`, `$ mkdir dirA/dirA_child`
- `$ rm -rf dirA` でdirA、dirA_child両方削除されたことを確認
- mv
- 演習
- `$ mkdir dir1`, `$ mkdir dir2`
- `$ mv dir2 dir1` でdir2をdir1内に移動
- 演習2
- `$ mv dir1/dir2 dir1/dir2_moved`
- <span style="background-color: #ff0;">mv>演習を指して「演習1」と書いているが、他にも演習があるのでややこしいのでは?</span>
- <span style="background-color: #ff0;">ここはAWS章のように名前変更と移動を別々にしっかり説明した方が良いと思う</span>
- cp
- `$ cp コピー元のファイル(ディレクトリ) コピー先のパス`
- `$ cp -R dir1 dir1_copy`
- tab補完
- 例ではworkspace_directoryというフォルダを用いている
- <span style="background-color: #ff0;">もっと分かりやすい名前にする/候補が複数ある場合、tabキー連打するとその候補一覧が表示されることを追加したい</span>
- history
- <span style="background-color: #ff0;">上述の通りWindowsが非対応なので、載せ方を考える</span>
- ↑、↓キー
### AWS > EC2でLinuxを学ぼう
#### ディレクトリ操作に関するコマンド
- pwd
- 実行結果
- ls
- オプションの説明
- `-l`,`-t`,`-r`,`-ltr`
- `$ ls -ltr /`の実行結果
- mkdir
- `$ mkdir test`後に`$ ls`を実行し、testフォルダが作成されたことを確認
- cd
- `cd`,`cd .`,`cd ..`の違いを説明
- `$ cd test`後に`$ pwd`
- `$ cd ..`後に`$ pwd`
- mv
- [名前変更] `$ mv test test1`で、既存のtestフォルダの名前をtest1に変更。`$ ls`で変更を確認。
- [移動] `$ mkdir test2`, `$ mv test1 test2`で、test1をtest2フォルダ内に移動。`$ ls test2`でtest2フォルダの中身を確認。
- rmdir
- `$ rmdir test1`後に`$ ls`。削除後は何もないので、何も出力されないことを確認。
- <span style="background-color: #ff0;">この前に`$ cd test2`要りません?</span>
- 演習問題(以下引用)
```
1)カレントディレクトリを確認します。
2)カレントディレクトリにあるファイルを確認します。
3)ディレクトリを新たに作成します。
4)ディレクトリができたことを確認します。
5)そのディレクトリの中に移動します。
6)元のディレクトリに移動します。
7)ディレクトリ名を「abcde」に変えます。
8)「abcde」ディレクトリを削除します。
```
#### ファイル操作に関するコマンド
- `>`
- ファイルが存在しない場合は、新たに作成される
- `>>`を使うと追記になる
- `$ echo 'Hello World' > ./test.txt`後に`$ ls`でtest.txtが作成されたことを確認
- cp
- copyの略
- `$ cp test.txt test1.txt`後に`$ ls`で確認
- rm
- removeの略
- `$ rm test.txt`後に`$ ls`で確認
- cat
- concatenateの略。本来は「つなぐ、連結する」の意味
- 他にもmore, tail, headなどがあります。調べてみましょう。
- `$ cat test1.txt`
- 確認問題(以下引用)
```
1)echo 'Hello Linux' の出力結果で、hello.txtファイルを作成します。
2)続けて、同じ内容を同じファイルに追記します。
3)hello.txtファイルをコピーして、hello1.txtファイルを作成します。
4)hello.txtファイルを削除します。
5)hello1.txtファイルの中身を確認します。
```
#### 覚えておきたい便利なコマンド
- find
- `find ファイル名`が基本書式
- `-name`オプションを用いて、ファイル名やディレクトリ名の一部を指定するワイルドカード検索も可能です。
- `$ sudo find / -name test1.txt`
- CLIに移管する場合、sudoは削除可
- <span style="background-color: #ff0;">上の方のワイルドカードの説明で似たようなことはした</span>
- `-name`でワイルドカードを指定しない場合は、引用符(")を付けなくても構いません。
- tail
- 指定したファイルの末尾10行を出力
- `-f`オプションを付けた場合、ファイルの内容が増えたときに新しい末尾を追加表示し、ファイル末尾を出力し続けます。処理を終了するには`Ctrl`+`c`を押します。
- 後ほど確認問題で実習します。
- `$ sudo tail -f ファイル名`
- 実際に増えることを確認してもらうのもアリ
- grep
- `$ grep He test1.txt`
- 例題では、test1.txtファイル内の「He」のある行を検索し、表示しています。
- こちらも後ほど確認問題で実習します。
- history
- grepコマンドと組み合わせると、過去に実行したコマンドを絞り込んで出力できます。
- `$ history | grep ssh`
- <span style="background-color: #ff0;">しれっと連結使ってる</span>
- 確認問題(以下引用)
```
Nginxが出力するアクセスログをアクセスと同時並行で確認する演習をします。
EC2インスタンスにログインした状態で、以下の手順をコマンドを確認しながら実行してください。
1)ターミナル上で、Nginxが出力するアクセスログ(access.logファイル)をtail -fで開きます。
access.logファイルの場所は、findコマンドで探してください。
2)パブリックIPアドレスにWebブラウザでアクセスし、Nginxで動いているページを表示します。
3)2でアクセスした結果が、tailコマンドを実行しているターミナルに追加表示されることを確認します。
4)IPアドレスの後ろに、「abc」を付けてアクセスします。
http://xxx.xxx.xxx.xxx(サーバーのパブリックIPアドレス)/abc
なお、ページにエラーが表示されてもOKです。
5)4でアクセスした結果が、tailコマンドを実行しているターミナルに追加表示されることを確認します。
6)ターミナルでCtrl + Cを押し、tailコマンドを終了します。
7)grepコマンドを用いて、access.logファイルから、abcページを表示した際のログを検索して表示します。
このように、tail -fでログを確認しながら操作をして、ログと見比べる方法はよく使われます。
また、grepコマンドを用いて、ログファイルからエラーを抽出したり、アクセスログから特定のアクセス情報を抽出することもよく使います。
何度も実行してコマンドの使い方を覚えましょう。
```
#### 便利なキー操作
- `↑`, `↓`キー
- `Ctrl`+`c`
- `Ctrl`+`d`
- 途中まで入力して`Tab`キー
#### コマンドを各自で調べるには
- google検索欄に「Linux コマンド xxxxx」
- xxxxxには調べたいことはエラー内容
- 例えば「Linux コマンド ファイルを探す」「Linux コピー コマンド」
- 既にコマンド名がわかっていてオプションが知りたい場合は「Linux コマンド名 オプション」
- man
- Linuxのオンラインマニュアルが表示され、機能やコマンドオプションを調べられます。
- 英語
- `$ man cp`
- オンラインマニュアルはスペースキーで改ページされ、`q`を押すと終了できます。
- Cloud9での動作確認OK
- <span style="background-color: #ff0;">WindowsはNG。~~helpコマンドが代替コマンドになります。~~ `$ コマンド名 --help`を利用しましょう。以下格闘ログ</span>
```
(1) 「$ help コマンド名」を実行したところ、以下メッセージで実行不可。
このコマンドはヘルプ ユーティリティでサポートされません。"コマンド名 /?" を試してください。
※これで表示できるコマンドもある模様。例: dir
しかしcp, lsなど代表的なものがNGだったため、あまりよろしくないかと。
多分"Windowsコマンド"ならこれでいけるんでしょう。
カリキュラムではほとんど紹介していないため、--helpに統一で良いと思います。
(2) 「$ コマンド名 /?」を実行したところ、以下メッセージで実行不可。
コマンド名: missing destination file operand after '/?'
Try 'コマンド名 --help' for more information.
(3) 結局「$ コマンド名 --help」と、--helpオプションになりました。
```