シェルスクリプト再入門


## 概要

- Unixコマンドをまとめたもの
- ループや条件分岐も可能で、プログラミングっぽく書ける
- 複雑な処理や面倒な処理を、シェルスクリプトで書いておくと、処理時間の短縮などが実現が可能

## 1. まずは実行権限を与える

```bash
$ touch test.sh
$ chmod +x test.sh
```

実行権限がなければ実行出来ないので、このように対象ファイルに`chmod +x`で実行権限を与えておきましょう。

## 2. 変数を使ってみる

注意して覚えておく事

- 変数を代入する場合は、`=`の前後にスペースを入れてはだめ
- 変数利用時は下記のようにして使える
	- `$hoge`
	- `"$hoge"
	- `${hoge}
	- `"${hoge}"`
- シングルクォートで囲ってしまうと変数展開されない

```bash
#/bin/bash

# 変数代入時は=の前後にスペース入れたらダメ
helloString="Hello"

# 下記のようにどのように括っても変数を利用可能
echo $helloString
echo "$helloString"
echo ${helloString}

# 文字列連結はつなげるだけで良い
echo ${helloString} ${helloString}

# シングルクォートで囲ってしまうと、変数展開されない
echo '$helloString'
```

##### 実行結果

```bash
Hello
Hello
Hello
Hello Hello
$helloString
```

## 3. 計算してみる

```
#/bin/bash

x=10

# このように計算式を書いても、ただの文字列として扱われてしまう
echo $x+2

# '`(バッククォート)'は、中の式を評価してその結果を返す
# exprは、後の文字列を数値として計算する
echo `expr $x + 2`
```

## 3. 計算をしてみる

四則演算をする上でも独自ルールがあったりするので注意しましょう。

- 計算を行う場合は、バックスラッシュで囲う
- 計算は、`expr`を使う
- 掛け算の時だけ、`*`の前に`\`を付ける
- 括弧で計算順序を処理する場合は、`()`をつけ、この括弧の前もバックスラッシュを付ける


```bash
#/bin/bash

x=10

# このように計算式を書いても、ただの文字列として扱われてしまう
echo $x+2

# '`(バッククォート)'は、中の式を評価してその結果を返す
# exprは、後の文字列を数値として計算する
# 全てスペースを入れる
echo `expr $x + 2`
echo `expr $x - 2`
echo `expr $x / 2`

# 掛け算の場合だけ、"*"の前にバックスラッシュを入れないとSyntaxErrorになってしまう
echo `expr $x \* 2`

# 掛け順を指定する場合括弧を使うが、その場合も括弧の前にバックスラッシュを入れる
echo `expr \( $x + 10 \) \* 100`
```

##### 実行結果

```bash
10+2
12
8
5
20
2000
```

## 4. 配列を扱う

- 配列を扱うには`()`括弧で囲う
- 要素にアクセスする場合は、`{}`中括弧と、`[]`括弧を使う
	- ex) `echo $`{x[1]}`
- 要素全てを出すには、`*`か、`@`を指定する
	- ex) `echo ${x[*]}`
	- 数を出すには、`#`を使う
		- ex) `echo ${#x[*]}`
- コマンドの実行結果も`()`括弧でくくうと、結果を配列に入れられる

```
#/bin/bash

# 配列は丸括弧で囲う
x=(2 4 6)

# 配列の変数をそのまま指定すると、先頭を指す
echo 'echo $x >>>' $x

# 配列の要素にアクセスする
echo 'echo ${x[0]} >>>' ${x[0]}
echo 'echo ${x[1]} >>>' ${x[1]}
echo 'echo ${x[2]} >>>' ${x[2]}
echo 'echo ${x[3]}(is not exist key) >>>' ${x[3]}

# 全ての配列を表示
echo 'echo ${x[*]}>>>' ${x[*]}

# 配列の要素数
echo 'echo ${#x[*]}(配列の要素数を調べる) >>>' ${#x[*]}
echo 'echo ${#x[@]}(配列の要素数を調べる) >>>' ${#x[@]}

# 配列に値を代入する
echo '代入前の2番目>>>' ${x[2]}

# 代入
x[2]=100

echo '代入後の2番目>>>' ${x[2]}

# 変数にコマンドの実行結果を配列に代入する
date=(`date`)
echo 'dateコマンドの実行結果の要素数>>> ' ${#date[*]}
echo 'dateコマンドの実行結果1番目 >>>   '${date[0]}
echo 'dateコマンドの実行結果2番目 >>>   '${date[1]}
echo 'dateコマンドの実行結果3番目 >>>   '${date[2]}
echo 'dateコマンドの実行結果4番目 >>>   '${date[3]}
echo 'dateコマンドの実行結果5番目 >>>   '${date[4]}
```

##### 実行結果

```bash
echo $x >>> 2
echo ${x[0]} >>> 2
echo ${x[1]} >>> 4
echo ${x[2]} >>> 6
echo ${x[3]}(is not exist key) >>>
echo ${x[*]}>>> 2 4 6
echo ${#x[*]}(配列の要素数を調べる) >>> 3
echo ${#x[@]}(配列の要素数を調べる) >>> 3
代入前の2番目>>> 6
代入後の2番目>>> 100
dateコマンドの実行結果の要素数>>>  5
dateコマンドの実行結果1番目 >>>   2017年
dateコマンドの実行結果2番目 >>>   9月19日
dateコマンドの実行結果3番目 >>>   火曜日
dateコマンドの実行結果4番目 >>>   14時10分32秒
dateコマンドの実行結果5番目 >>>   JST
```

## 5. 比較

testコマンドによる比較をまとめておきます。

オプション|略名|仕様例|説明
---|---|---|---
-eq|equal|test `${x}` -eq `${y}`|xとyがイコールならtrue
-ne|not equal|test `${x}` -nq `${y}`|xとyが`!=`(ノットイコール)ならtrue
-gt|grater than|test `${x}` -gt `${y}`|x > yならtrue
-ge|grater than or equal|test `${x}` -ge `${y}`|x >= yならtrue
-lt|less than|test `${x}` -lt `${y}`|x < yならtrue
-le|less than or equal|test `${x}` -le `${y}`|x <= yならtrue

一通り示した例

`$?`というのは、直前の評価式の結果を表しており、下記のようになります。
- 0: 正常終了
- 0以外: 異常終了

```bash
#/bin/bash

# -eq
test 2 -eq 3;
echo '2 === 3の実行結果は >>> ' $?
test 2 -eq 2;
echo '2 === 2の実行結果は >>> ' $?

# -ne
test 2 -ne 3;
echo '2 !== 3の実行結果は >>> ' $?

# -gt
test 2 -gt 2;
echo '2 > 2の実行結果は >>> ' $?

# -ge
test 2 -ge 2;
echo '2 => 2の実行結果は >>> ' $?

# -lt
test 2 -lt 2;
echo '2 < 2の実行結果は >>> ' $?

# -le
test 2 -le 2;
echo '2 =< 2の実行結果は >>> ' $?
```

##### 実行結果

```bash
2 === 3の実行結果は >>>  1
2 === 2の実行結果は >>>  0
2 !== 3の実行結果は >>>  0
2 > 2の実行結果は >>>  1
2 => 2の実行結果は >>>  0
2 < 2の実行結果は >>>  1
2 =< 2の実行結果は >>>  0
```