Linuxの基本的なコマンドを解説してみた

## はじめに

Linuxコマンドについて学習したので、いくつかコマンドを紹介していきます。
改めて調べていくと、よく使うコマンドでも「こんな便利な機能あったのか～！」となるものが多くありました。


## 前提

まず、コマンドの説明時に登場する単語や記号の意味を簡単に説明していきます。

### ディレクトリ

Windowsでのフォルダにあたるものです。
呼び方が違うだけと思っていただいて差し支えありません。

図を使いながらがわかりやすいかと思いますので、下の図を見てください。
![dhirectorytree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518748/32101de7-8519-6257-fa63-55314a93e1d9.png)
自身がcurrentに居るとして、
- currentは`カレントディレクトリ`
- parentは`親ディレクトリ`
- childは`子ディレクトリ`または`サブディレクトリ`

と呼ばれます。

また、当画像で一番上の階層であるrootは`ルートディレクトリ`と呼ばれており、実際にLinuxを利用する際は`/`で表されます。
Windowsで表すと、`C:\`がこれにあたりますね。
違いとしては、Windowsでは`C:\`や`D:\`など複数ルートディレクトリが存在する場合がありますが、Linuxではルートは`/`の１つだけです。

そして、図には現れていないのですが、`/home/<ログインユーザー名>`のディレクトリを`ホームディレクトリ`と呼びます。
基本的に、自身の作業を行う場合は、このホームディレクトリで行うことが多いです。

### 相対パス/絶対パス

ディレクトリの場所を記述する方法として、`相対パス`と`絶対パス`があります。

例えば、道を説明するにあたって、近所であれば
「２個目の角を左に曲がって、１個目の信号を右に曲がって右手の建物です。」
のように、自身の現在地基準で場所を表すかと思います。

また、離れた場所でよく知らない土地の場合、
「〇〇県△△市...」
のように、住所で示すかと思います。

これらの前者の考え方が`相対パス`、後者が`絶対パス`にあたります。

先程のディレクトリの説明に使った図に再登場してもらいましょう。
![dhirectorytree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518748/1d55ef29-9135-19f4-f728-8ab0cbc514d3.png)

この時、currentからjennyへのパスを示したいとします。
相対パスの場合、`../brother/child/jenny`
絶対パスの場合、`root/parent/brother/child/jenny`
となります。


### 標準出力/標準入力/標準エラー出力

#### 標準出力

コマンドなどにおいて、結果がコンソールに表示される場合がありますが、おおよそ、その出力のことです。
例えば、下記画像の赤枠で囲った範囲が標準出力です。
![標準出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518748/c1440a0a-d2bc-9a6e-7384-1e50da278ae1.png)

#### 標準入力

外部からデータを受け取る方法で、キーボード入力やファイルの内容をプログラムに提供します。
こう書かれてもピンと来ませんね。

紹介するコマンドには含まれていないのですが、`echo`というコマンドは、標準入力をそのまま標準出力として返してくれます。

例えば、`echo Hello!`と送ると、`Hello!`が標準出力として表示されます。
この時、echoに標準入力として`Hello!`が提供されています。

#### 標準エラー出力

標準出力の際、おおよそ、と記述しました。
表示される見た目は同じようなものなのですが、エラーメッセージは標準出力とは区別されています。

例えば、存在しないディレクトリを削除しようとすると、下記の赤枠ような標準エラー出力が表示されます。
![標準エラー出力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518748/35d9e6d3-4f38-f750-6ea7-63b7a398e0c9.png)

### 記号の意味

コマンド使用時に登場する記号がいくつかあるので、さっくりと説明していきます。

| 記号 | 例 | 読み方 | 意味 |
|:-:|:-:|:-:|:-:|
| > |command > file | リダイレクト | コマンドの標準出力をファイルへ出力する（上書き）|
| >> |command >> file | リダイレクト | コマンドの標準出力をファイルへ出力する（追記）|
| < |command < file | リダイレクト | ファイルから標準入力をコマンドへ供給する |
| \| |command1 \| command2 | パイプ | command1の標準出力をcommand2の標準入力として渡す|
| && |command1 && command2 | アンパサンド | command1が正常終了した場合、command2を実行します|


## コマンド紹介

ここから、コマンドの紹介を行っています。

コマンド例の書き方として、以下のようなルールで記載しています。
- `[]`囲いは省略可。
- `<>`囲いは必須。


### cd

`c`urrent `d`irectory

```
cd [オプション] [ディレクトリ]
```
ディレクトリの移動に使用します。
オプションを使うことはまずないと思います。
実務でもオプション指定したことは、今のところありません。
それよりも、パスの指定を効率よく行えることのほうが大切。

それには、いくつか特殊な書き方を覚えて置く必要があります。
| 書き方 | 意味 | 概要 |
|:-:|:-:|:-:|
| . |カレントディレクトリ|現在のディレクトリ|
| .. |親ディレクトリ|１つ上のディレクトリ|
| / |ルートディレクトリ|「/」ディレクトリ|
| ~ |ホームディレクトリ|「/home/[ユーザー名]」ディレクトリ|

例えば、
- /etcディレクトリ下のファイルにアクセスしたい際、全く違う階層からでも`cd /etc/...`のように書ける。
- 自身の作業ディレクトリ[^1]へ移動したい場合、`cd ~/...`のように書ける。
- 親ディレクトリの持つファイルにアクセスしたい場合、`cd ../<ファイル>`のように相対パスで指定。

などを覚えておくと、素早く移動したいパスを指定できるようになります。
また、ホームディレクトリへの移動については、`cd`だけの実行でも移動できます。

### pwd

`p`rint `w`orking `d`irectory

```
pwd [オプション]
```
自分がどのディレクトリで作業しているのか、パスを返してくれます。
オプションを使うことはまずないと思います。
実務でもオプション指定したことは、今のところありません。

### ls

`l`i`s`t説もあれば、
`l`ist `s`egments説もあります。

segmentsについては、自分の産まれるはるか昔の1960年代開発されたMulticsというOSがあり、そこではsegmentsがファイルを指していたそうな…
要は、ファイルをリストする、なるほどですね。

```
ls [オプション] [ディレクトリ]
```
ディレクトリを指定した場合、指定ディレクトリ下のコンテンツが表示されます。
省略した場合、カレントディレクトリのコンテンツが表示されます。

オプションについては、`-al`はとりあえず付けとけ、くらいよく使います。
いくつか、自分が実際使ってるなーと思うオプションを以下にあげます。
|オプション|意味|
|:-:|:-:|
|a|隠しファイル[^2]を非表示にしない|
|l|ロング形式で表示|
|r|ソートを逆順（降順）にする|
|t|タイムスタンプで昇順ソート|

ロング形式ってなんぞ？って感じだと思いますので、イメージ画像を貼ります。
![lsオプションl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518748/c40968e0-1117-4733-60e0-b56a9839916c.png)
注目する箇所を囲んでいます。

`r/w/x/-`が書いてある、緑＝ユーザー（所有者） 黄＝グループ 赤＝その他 のパーミッションをそれぞれ表しています。
また、パーミッションの囲いと同じ色で`root`や`zumi`が囲まれていますね。
対応する色が、それぞれユーザー名（所有者名）、グループ名です。

そして、`r/w/x`や`パーミッション`って何？って話ですが。
| 表示 | 意味 |
|:-:|:-:|
|r|読み込み|
|w|書き込み|
|x|実行|

の許可（パーミッション）があるか？を表しています。
この画像の場合、その他のユーザーにはほぼ書き込み許可がありません。
例え、vimでテキストを開いても、読み取り専用でしか開けないということになります。

プログラムからファイルやフォルダの生成をしたりする際、これが原因でうまくいかない事もあります。
確認方法、覚えておきましょう。

変更の仕方は、後述の`chmod`で説明します。

### mkdir

`m`a`k`e `dir`ectory

```
mkdir [オプション] <ディレクトリ>
```
ディレクトリを作成する際に使用します。

また、深いディレクトリを作成したい場合に、
```
mkdir totemo
cd totemo/
mkdir mendoi
```
なんて書きたくないですよね。

`-p`オプションで、目的のディレクトリまでの間がなかった場合、作ってくれます。
```
mkdir -p korenara/rakudane
```


### rmdir

`r`e`m`ove `dir`ectory
```
rmdir [オプション] <ディレクトリ>
```
空のディレクトリ専用の削除コマンド。

空でないと削除できないのでセーフティではあるものの、あまり使っていません。

### cat

con`cat`enate

```
cat [オプション] [ファイル]
```
ファイルの内容を標準出力に連結（結合）します。

自分は、中身を見る前から内容が少ないとわかっているときくらいしか使わないです。
大抵の場合、後述する`less`コマンドを使っています。

正直、あまり使わないので使い道が浮かばないのですが、
`cat 20230815.log 20230816.log 20230817.log > 20230815-17.log && less 20230815-17.log`
のように、３日分まとめてみたい時なんかに、catで３ファイルを連結してファイルに出力し、lessで出力後ファイルを見るとかでしょうか。
そうすると、１ファイルとして表示でき、検索を各ファイルでやって目的のログを探すような手間が省けるので。


### less

別にある`more`コマンドに対して`less`ということのようです。
その`more`の由来は調べてもわかりませんでした。。。

```
less <ファイル>
```
指定のファイルを表示します。

起動が早く、vim同様に検索やファイルの先頭/末尾への移動コマンド等が使えます。
これらの操作方法は、前回記載しているので割愛します。

https://qiita.com/john_HC20230703/items/5fced74a3d574f50e951

また、`less`でファイルを表示した状態で`shift + f`を入力すると、リアルタイムな変更を読み込んでくれます。
次に紹介する`tail`コマンドに`f`オプションを付けたときと同様の動きですね。

更に、`less`の場合は目的のログが表示された瞬間に`ctrl + c`で読み込みを止められるので、ログの更新量が多く、すぐ流れてしまうような時に役立ってくれそうです。

### tail

```
tail [オプション] [ファイル]
```
オプションなしだと、ファイルの末尾から10行を表示します。

```
tail -n [行数] [ファイル]
```
`n`オプションで、表示する行数を指定できます。

自分は、`tail -f`でログなどのリアルタイムな更新があるものを見るのに使っています。
`less`でもできるのですが、忘れがちで気づけばこっちを使ってたりしますｗ

### touch

```
touch [オプション] <ファイル>
```

新しい空のファイルを作る際に使われるイメージが強いです。
既存のファイルに対して実行すると、`Access Time`、`Modify Time`と`Change Time`が現在日時に更新されます。

今のところ、タイムスタンプの更新をしたいという場面に出会っていませんが。
`a`オプションでファイルへの`Access Time`を現在時間に更新。

```
touch -t <[[CC]YY]MMDDhhmm[.ss]> <ファイル>
```
で、`Access Time`と`Modify Time`を指定時刻に変更できます。

なんだか色んなタイムスタンプが出てきましたが、`ls`でデフォルトで表示されているのは、`Modify Time`です。
（※オプションで他のタイムスタンプを表示することもできます。）
その他をまとめて確認したい場合、`stat <ファイル>`で見ることができます。

また、ファイル作成時に、大量に作りたいときなんかに楽に書く方法として、下記のような書き方がかあります。
```
touch {1..100}.txt
```

### rm
 
`r`e`m`ove

```
rm [オプション] [ファイル]
```
ファイルの削除を行うコマンドです。
オプションを付けることで、ディレクトリの削除や、ディレクトリごと中身を削除することもできます。

よく使うなーというオプションをあげておきます。
|オプション|意味|
|:-:|:-:|
|i|削除の前に確認を行う|
|r|再帰的に削除を行う|
|f|確認なく強制的に削除を行う|
|v|削除したものを表示する|


先に出てきた`rmdir`でやりたいこともできるので、実際こちらを多く使うことになります。
ただし、いくつか気をつけなければいけないことがあります。

:::note alert
- 基本的に、削除すると復元できない。
- 確認なく削除させることができる。
:::

つまり、下手をすると必要なファイルを、まるっと完全に消してしまうことがあるということです。
やってみたという記事を書かれている方がいらっしゃいましたので、貼らせていただきます、

https://qiita.com/belgianbeer/items/a3ecfe739fea84f4a3fc

事故を防ぐために事前の対策と、日頃から意識していることです。

:::note info
- 入れて良い環境であれば、`gomi`[^3]コマンドをインストールし、`rm`のalias[^4]に設定しておく。
- `rm`のaliasに`rm -i`を設定しておく。（設定していても、`-f`を書くと後勝ちなので、確認されません。）
- `-rf`はむやみに付けない。
- `-f`を使用する際は、可能な限りコマンドの最後に付けるようにする。
- `-v`を使用し、何を削除したのか表示させる。
- Enterキーを誤って押下する可能性を下げるために、右のshiftキーは使わない。
:::

今となってはこういった対策がとれますが、初期は`i`オプションなんてなかったそうです。
恐ろしいですね。

### mv

`m`o`v`e

```
mv [オプション] <対象> <移動先>
mv [オプション] <対象> <移動先ディレクトリ>
mv [オプション] -t <移動先ディレクトリ> <対象>
```
ファイルのリネームや、移動を行います。
ディレクトリごと移動することや、複数対象をまとめて指定のディレクトリ下へ移動することもできます。

使うオプションは、おおよそ`rm`コマンドと似通っています。
|オプション|意味|
|:-:|:-:|
|i|削除の前に確認を行う|
|r|再帰的に削除を行う|
|f|確認なく強制的に削除を行う|

`rm`コマンド程ではないですが、こちらも少し注意点があります。

:::note warn
- 確認なく既存ファイルを上書きする場合がある。
- パーミッションは基本的に移動前のものを引き継ぐ。
:::

こちらの対策や、注意していることです。

:::note info
- `mv`のaliasに`mv -i`を設定しておく。（設定していても、`-f`を書くと後勝ちなので、確認されません。）
- `-f`を使用する際は、可能な限りコマンドの最後に付けるようにする。
- 先に、移動先に指定したい名前と同じものがないか確認しておく。
:::


### cp

`c`o`p`y

```
cp [オプション] <対象> <移動先>
cp [オプション] <対象> <コピーディレクトリ>
cp [オプション] -t <コピー先ディレクトリ> <対象>
```
ファイルのコピーを行います。
ディレクトリごとコピーすることや、複数対象をまとめて指定のディレクトリ下へコピーすることもできます。

使うオプションは、おおよそ`rm`コマンドと似通っており、`mv`コマンドと被るので省きます。

注意点や対策も、`mv`コマンドと同じ内容になるので、割愛します。

ちょっとした書き方のことですが、下記のように書くこともできます。
これは、`mv`も同様です。
```
cp {before,after}.txt
```

### ln

`l`i`n`k

```
ln [オプション] <対象> <リンク名>
ln [オプション] <対象> 
ln [オプション] <対象> <ディレクトリ>
ln [オプション] -t <ディレクトリ> <対象>
```
ファイルのリンクを作ることができ、リンク名を指定することも可能です。
複数ファイルのリンクを、指定のディレクトリ下に１コマンドで作成したりもできます。

自分は、`s`オプションの`シンボリックリンク`くらいしか使った事がないです。
`シンボリックリンク`とは、馴染みがあるところでいうとWindowsでのショートカットのようなもので、実体（ショートカットで指定しているもの）が消えたり、場所が変わるとリンクが壊れます。

これとは異なりオプション無しで使用すると、`ハードリンク`を作成します。
`ハードリンク`は余り馴染みのあるところではないのですが、`シンボリックリンク`との違いとしては、リンク元を削除してもリンク先は残ります。
自分はほとんど使った記憶がありません。

### find

```
find [探す場所] [<何で検索するか> <検索値>]
```

探しものを検索できます。
名前やファイル種別、サイズなどを検索値として使え、組み合わせることで色々な検索が可能です。

```
find [探す場所] -name "*.<拡張子>"
```
のように、ワイルドカードを利用し、特定の拡張子が付いたファイルを探すような使い方が多いでしょうか。

使い道の多いコマンドですので、何か探しものがある際、「どうやったら欲しいものが見つけられるかな？」と考えながら、慣れていきましょう！

### chmod

`ch`ange `mod`e

```
chmod [オプション] <パーミッション> <対象>
chmod [オプション] --reference=<参照元> <対象>
```
パーミッションの変更を行います。
自分で指定する方法と、参照元と同じ設定にする方法があります。

`ls`コマンドの説明時に、`rwx`のそれぞれの意味、また所有者/グループ/その他でパーミッションが分かれているということでした。
今回は、それの設定を行います。

パーミッション設定の記述方法が２通りあります。
- `chmod ①②③ <対象>`
①はu/g/oで指定（ユーザー/グループ/その他）。複数指定も可。
②は+/-/=で指定（追加/削除/設定）
③はr/w/xで指定（読み込み/書き込み/実行）。複数指定も可。
```linux:example
// ユーザーに実行許可を与える場合
chmod u+x test.txt
```
- `chmod <オクタルモード> <対象>` 
オクタルモードという言葉自体は覚えておく必要はないと思います。
`r=4`、`w=2`、`x=1`として扱い、設定したい権限の数値の合計を設定値して使います。
また、ユーザー/グループ/その他を全て設定するため、３桁の数字がオクタルモードの箇所に入ることになります。
```linux:example
// ユーザーには全て許可、グループ/その他には読み込みと実行を許可する場合
chmod 755 test.txt
//    ugo
```

また、`R`オプションを使用することで、指定ディレクトリ以下に全て同じ設定を行います。

### chown

`ch`ange `own`er

```
chown [オプション] [ユーザー] [:[グループ]] <対象>
chown [オプション] --reference=<参照元> <対象>
```
対象のユーザーやグループを変更します。
自分で指定する方法と、参照元と同じ設定にする方法があります。

`chmod`同様、`R`オプションを使用することで、指定ディレクトリ以下に全て同じ設定を行います。

### ps

`p`rocess `s`tatus

```
ps [オプション]
```
プロセスの確認を行います。

`プロセス`とは、コンピュータ上で実行されるプログラムの個別の実体を指します。
Windowsだと、`ctrl + shift + ESC`で起動できるタスクマネージャを開くと、プロセスが見れるので、それをイメージとして持っていただくと良いと思います。

このコマンドは大抵の場合、`aux`オプションを付けて使用します。

| オプション | 意味 |
|:-:|:-:|
| a | 全てのユーザーのプロセスを表示 |
| u | ユーザー指向の詳細情報表示 |
| x | 制御端末がないプロセスも表示 |

`a`オプションはわかるとして、`u`/`x`の説明はよくわからないですね。

さっくりとした説明ですが、
`u`は、CPU使用率やメモリ使用率など、ユーザーの知りたい情報を表示してくれる。
`x`は、ユーザーの意識しないところで動作しているプロセスを表示してくれる。
と認識してもらえればいいかと思います。

まとめると、意識していない範囲を含めてプロセスの状態を見やすく、全ユーザー分抜けなく表示してくれるので、使い勝手の良いオプションとなっています。

### kill

```
kill [オプション] <pid> [...]
```
プロセスを◯すことが出来ます。
[...]の部分は、複数のpidを同時に記載し、複数プロセスに対して行うことが可能という意味です。

この`pid`ですが、`process id`の略であり、先程の`ps`コマンドで表示されています。
なので、下記のような流れで使うことになると思います。
（※実際は、その前にどのプロセスをどういった理由で削除するのかみたいな話もあり、それを調べる工程もあるわけですが…）
```:example
// まず、プロセスを確認
ps aux
// ずらっとプロセスが表示される
// killコマンド使って削除する
kill <消したいプロセスのpid>
```

上記の例ではオプション無しですが、それは`-15`を付けていると見做されます。
この`-15`というのはシグナルを指しており、どのようなものがあるかは`kill -l（-Lでも良い）`で一覧表示されます。

よく使われるのはオプション無しの`-15`の`SIGTERM`と、`-9`の`SIGKILL`です。
余り正確なアナロジーとは言えないのですが、`SIGTERM`はシャットダウン、`SIGKILL`は電源ぶち抜きみたいなものです。

名前の通り、強力なコマンドですので、使用時は誤ったプロセスに対して行わないよう気をつけましょう。
また、基本的には`SIGTERM`を使い、それでも終了できない時に`SIGKILL`を使用するようにしましょう。

### man

`man`nual

```
man <コマンド>
```

ここまでいくつかのコマンドを説明してきて、個人的によく使っているなという例をあげてきました。
しかし、その他にも多くの使い方があります。

そこで、この`man`コマンドを使用すると、使用にあたっての詳細情報が見られます。
「こんな機能ないかな？」と思ったら、使ってみて下さい。

[^1]:通常、自身の作業スペースは`/home/[ユーザー名]`ディレクトリ下を使用します。
[^2]:`.`から始まるファイルのことで、このオプションを付けないと表示されません。
[^3]:ゴミ箱機能が使えるので、誤って消しても復元できるようになります。
[^4]:あだ名みたいなもので、rmコマンドを打ったとしても、gomiコマンドを実行します。