shell scriptを理解したい vol.2

# はじめに

前回の記事はこちら→[shell scriptを理解したい vol.1](https://qiita.com/Mittag-tech/items/f009f38da1efe4b596ae)

# 基本的なところその2

前回に引き続いて[【bash入門】bashシェルスクリプトの書き方](https://tech-blog.rakus.co.jp/entry/20210525/shellscript)を参照

## 配列の定義

```bash
#!/bin/bash

arr_var=(0 1 2 3 4 5)
```
> <code>,</code>で区切ると思っている出力にならない。結果は後述。

### 先頭の内容を参照

```bash
#!/bin/bash

echo $arr_var # 0
```
これが<code>,</code>で区切っていると

```bash
#!/bin/bash

arr_var_miss=(0,1,2,3,4,5)
echo $arr_var_miss # 0,1,2,3,4,5
```
<code>,</code>も1文字と見られてるっぽい。配列にしたければ半角スペースで対応すること。

### 任意の配列番号の内容の参照

```bash
#!/bin/bash

echo "${arr_var[2]}" # 2
echo "${arr_var[-1]}" # 5
```
<code>,</code>で区切ってると0以外は空白を出力する→存在しないところを参照していることになっている。

### 配列の内容を全て参照

```bash
#!/bin/bash

echo "${arr_var[@]}" # 0 1 2 3 4 5
```

> @を使うと"全て"を意味するんだろうか？

## for文

基本的な書き方は以下

```bash
#!/bin/bash

for i in `seq 0 5`
do
    echo $i
done

# 0
# 1
# 2
# 3
# 4
# 5
```

<code>seq</code>で<code>i</code>に代入する区間を指定、今回だと0~5。

配列の長さ分だけ回すことも可能

```bash
#!/bin/bash

for i in ${arr_var[@]}
do
    echo $i
done

# 結果は同じなので省略
```

## while文

基本的な書き方は以下

```bash
#!/bin/bash

count=0

while [ $count -lt 5 ]
do
    count=$((++count))
    echo $count
done
```

> 条件の部分(コード内<code>[ $count -lt 5 ]</code>)は後述if文で説明

急に知らない書き方が出てきたので少し脱線

### 変数の値のインクリメント

[シェルスクリプトで変数の値をインクリメントするときの書き方](https://monologu.com/increment-variable/)を参照

> [インクリメント](https://e-words.jp/w/%E3%82%A4%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%A1%E3%83%B3%E3%83%88.html)：増加、増分などを意味する、コンピュータ用語では値に1を加えることを指す。逆に1減じる場合はデクリメントという。

インクリメントの仕方は大きく2つ

1. <code>expr</code>を使う
2. bashの算術式展開を使う

#### <code>expr</code>を使う

```bash
#!/bin/bash

count=0

while [ $count -lt 5 ]
do
    count=`expr $count + 1` # 変数countに1を加えて変数countに再代入
    echo $count
done
```

#### bashの算術式展開を使う

```bash
#!/bin/bash

count=0

while [ $count -lt 5 ]
do
    count=$((++count))
    echo count
done
```

先述の<code>expr</code>を使う場合と同じ出力が得られる。

```bash
1
2
3
4
5
```

<code>count=$((++count))</code>を<code>count=count=$((count++))</code>にするとインクリメントのタイミングが変わる。

```bash
0
1
2
3
4
```

話を戻して...

### readコマンドを使った処理

ファイルの中身を書き出すなどで使える。

```text
# test.txt

hoge
foo
hogefoo
```

test.txtの中身をコマンドラインに書き出してみる。

```bash
#!/bin/bash

while read line
do
    echo $line
done < test.txt
```

## if文

基本的な書き方は以下

```bash
#!/bin/bash

if [ 条件1 ]; then # thenを改行せずに一行で書くのが一般的らしい、改行しても動作は変わらない。
    処理1
elif [ 条件2 ]; then
    処理2
else
    処理3
fi
```

条件式は以下のものが使える。

算術演算子の場合

|比較演算子|処理|コマンドの意味|
|---|---|---|
|var1 -eq var2|var1=var2なら正|equal|
|var1 = var2|同上||
|var1 -ne var2|var!=var2なら正|not equal|
|var1 != var2|同上||
|var1 -gt var2|var>var2なら正|greater than|
|var1 -ge var2|var1>=var2なら正|greater equal|
|var1 -le var2|var1<=var2なら正|less equal|
|var1 -lt var2|var1<var2なら正|less than|

文字列比較の場合
|比較演算子|処理|
|---|---|
|-e /testfile|testfileが存在すれば正|
|-f /testfile|testfileが存在してかつ通常ファイルなら正|
|-d /testfile|testfileが存在してかつdirectoryなら正|
|-z <文字列>|文字列の長さが0なら正|
|-n <文字列>|文字列の長さが0でなければ正|

> 他にもいっぱいありそうなので調べたら追記

## case文

基本的な書き方は以下

```bash
#!/bin/bash

case var in 
    var1 )
        処理1
        ;;
    var2 )
        処理2
        ;;
    * )
        処理3
esac
```

> ifやcaseは最後に逆さ文字を書いて締める、が定型みたい

# とりあえず

参考にしたサイトに書かれていた内容はある程度理解できたかな？

追加で自分が見たコードを元に更に情報を追加する予定。