シェルスクリプト基本知識

## 0: 超基本

### 用語

- **シェル**(*shell*)
   - UNIX系OSにおいて、コンピュータの中核機能(カーネルと呼ばれる)にユーザーがアクセスするためのインターフェース（仲立ち）となるソフトウェアのこと。
- **UNIX系OS**(*Unix-like*)
   - UnixというOSと似たような動きをするOS群の事。Linux, Solaris, MacOSなどが含まれる。Windowsは含まない。
-  **シェルスクリプト**(*shell script*)
   -  シェルは通常画面にコマンドを入力していく。が、毎回入力する手間を省くため、実行すべきコマンドをあらかじめファイルに書いておいたものをシェルスクリプトという。

参考：[シェル-Wikipedia](https://ja.wikipedia.org/wiki/シェル#コマンドラインシェルの一覧)
[Unix系-Wikipedia](https://ja.wikipedia.org/wiki/Unix系)

### シェルの種類

Bシェル系とCシェル系に別れ、それぞれに複数のシェルが存在する。

とりあえずBシェル系の一種である**Bash**が高機能である上にLinuxやMacOSのデフォルトのシェルとなっているので、シェルの基本を学んでいるような方（私を含む）の場合はBashを学べばいいだろう。

### シェルの置き場所

意識する頻度が多いのは`/usr/bin`フォルダと`/usr/local/bin`フォルダである。

- `/usr/bin`: 通常、（システムではなく）ユーザーが使うと考えられるコマンドが最初から一通り格納されているフォルダ。
- `/usr/local/bin`: ユーザーが自分で入れたコマンド（自作や、他人が作ったものをインストール）を格納するフォルダ。

参考: [/bin, /usr/bin, /usr/sbin, /usr/local/bin の違いとは？](https://qiita.com/valzer0/items/67a4c8bf2b1be0fc825a)

## シェルスクリプト作成の流れ

### 基本となるコマンド

[コマンドライン 初級〜中級者に役立つコマンド７選（逆引き）](https://qiita.com/satoru_pripara/items/60cbd0f10ae39e3f7a9f)

### 作成~実行までの流れ

```
$ vi hello   # テキストエディタなどで新規ファイルを作成
$ chmod +x hello    # ファイルの実行権限を付加
$ ./hello   # シェルスクリプト実行
```

### 作成

作成例

```
#!/bin/sh

echo 'Hello World!'
```

- 最初の行に`#!/bin/sh`を追加する。そのほかbashがある環境では`#!/bin/bash`、zshがある環境では`#!/bin/zsh`などと記載しても大丈夫だが、`sh`と記載するのが一番移植性は高くなる。

- シェルスクリプトは、`vi`コマンドを用いて作成してもいいし、他の任意のテキストエディタを用いて作成してもいい。

- スクリプト内の改行はLFのみにする必要がある。UNIX系OSでは改行コードはLFのみであるため何も気にしなくていいが、WindowsはLF＋CRで表されるため注意。
   - ちなみにLF(Line Feed)はカーソルを真下に下げる事、CR(Carriage Return)はカーソルを先頭に戻す事を表すASCII文字コードのこと。

参考: [Wikipedia - 改行コード](https://ja.wikipedia.org/wiki/改行コード)
[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 - CRとLFのちがい](https://wa3.i-3-i.info/diff129crlf.html)

## 変数の扱い

### シェル変数

- 変数の代入と参照

```
# 変数の宣言・代入: 変数名=値
# 変数の値を参照: $変数名　または ${変数名}

#例

message=123
echo $message # 123と出力される

message=hogehoge
echo $message # hogehogeと出力される

message='Hello World'
echo $message # Hello Worldと表示される。

echo ${message} # Hello Worldと表示される
```

- 値の代入の際は、スペースや特殊記号がシェルにより解釈されるのを防ぐため、シングルクオート('')で囲むと良い。
- なお=の前後にスペースを入れてはいけない。

```
message='Hello World'
```

- 変数の参照の際は、値に含まれるスペースや*などの文字が解釈されてしまうのを防ぐため、全体をダブルクオート("")で囲むと良い。

```
echo "$message"
```

- 宣言もしていない変数の参照を行うと、空文字が出力される。エラーにはならない。

```
echo "$hogehoge" # 空行が出力される
```

## 配列

複数の値を格納する変数として、配列を定義することができる。

```
# 例
array[3]='hello world'
echo "${array[3]}"
```

- 参照時は、必ず${}をつけないと正しい値が出てこないため注意。さらに、通常のシェル変数と同じく、ダブルクオートで囲んで`"${array[0]}"`などとすると良い。

- 添字には数字のみならず、別の変数を入れたり、または数字の計算式を入れても良い。

```
# 例
I=5
array[I]='fifth'
echo "${array[5]}" # fifthと表示される
echo "${array[2+3]}" # fifthと表示される
```

- 配列へ値を一括して代入、および一括して参照ができる。

```
# 一括代入

array=(one two three)
echo "${array[0]}" # oneと表示される
echo "${array[1]}" # twoと表示される
echo "${array[2]}" # threeと表示される

# 一括参照
echo "${array[@]}" # one two three と表示される
```

# 関数

## 宣言　


```
function test() {
}

// or you can declare a function without keyword "function"

test() {
}
```

# 位置引き数

[3.4.1 Positional Parameters](https://www.gnu.org/software/bash/manual/html_node/Positional-Parameters.html)
[3.4.2 Special Parameters](https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html)


## 参考文献

「[改訂第3版]シェルスクリプト基本リファレンス-----#!/bin/shで、ここまでできる」, 山森丈範, WEB+DB Press plus, 技術評論者, 2018