シェルプログラミング入門 1

# 概要

入門UNIXシェルプログラミングを読んでいく

## はじめに

 ```terminal
% echo $SHELL  #今使ってるシェルの種類を調べる
/bin/zsh
```

ここでは主にBシェルを使用する。
`ksh`,`bash`,`zsh`はBシェルを拡張したものなので同じことができる。
ただし、`csh`,`tcsh`はCシェル系なので文法は異なる。

# 基本

## とりあえず1つ作ってみる

1行目には`#!/bin/sh`とshを使うことを示す。

```sh:append
#!/bin/sh  
case $# in
    1 ) cat >> $1 ;;
    2 ) cat $1 >> $2 ;;
    * ) echo "Usage: append [fromfile] tofile" 1>&2 ;;
esac
```

これはあるファイルを別のファイルにくっつけるシェルスクリプトである。

```terminal
% ls -l
total 8
-rw-r--r--  1 Tomoki  staff  127  4 16 09:17 append
```

appendと同じディレクトリに以下の2つのファイルを作る。

```txt:abc
abcdefg
```

```txt:xyz
123456
```

そして中身を確認

```terminal
 % ls -l
total 24
-rw-r--r--  1 Tomoki  staff    7  4 16 09:23 abc
-rw-r--r--  1 Tomoki  staff  127  4 16 09:17 append
-rw-r--r--  1 Tomoki  staff    6  4 16 09:24 xyz
```

先ほど作った`append`プログラムを使ってみる。

```terminal
% ./append abc xyz
zsh: permission denied: ./append
```

`-rw-r--r--`は作った本人は読み書きでき、他の人は見ることだけできるファイルであるという意味。
実行する許可を与えなければならない。
`chmod`コマンドを使う。

```sh
% chmod +x append  #許可を与える
% ./append abc xyz #xyzファイルにabcの内容を付け加える
% ls -l           
total 24
-rw-r--r--  1 Tomoki  staff    7  4 16 09:23 abc
-rwxr-xr-x  1 Tomoki  staff  127  4 16 09:17 append
-rw-r--r--  1 Tomoki  staff   13  4 16 09:30 xyz
```

きちんとxyzの容量が13に増えている。
これでappendというシェルプログラムを1つ作ることができた。

重要なことをまとめると

* シェルプログラムの先頭には`#!/bin/sh`を付けないといけない
* シェルプログラムには実行権限を与える必要がある

## コメントアウト

`#`を付けるとコメントアウトできる。

## 改行を無視する

シェルスクリプトは1つのコマンドを1行に書かないといけない。
しかし、`\`を付けると最後の改行を無視することができる。

```zsh
% echo Hello \
World
Hello World

#スペースを複数入れても1つのスペースになってしまう
% echo Hello     \   
World
Hello World

#"を使うとスペースの個数を認識する
% echo "Hello    \ 
World"
Hello    World
```

## ワイルドカード

ワルドカードとは不特定の文字列を一括で置き換えたい時などに使われるもので、例えば以下のようなものがある

| 1       | 2 　　　|
|:-:      |:-:|
| *       | 文字列全部 |
| ?       | 1文字 |
| [...]   | []の中に含まれる文字どれか1つ |
| [!...]  |  []の中に含まれない文字|

## 隠しファイル

`.`で始まる名前のファイルを隠しファイルという。
隠しファイルの場合、ワイルドカードを使う際に始めの文字が`.`であることを明示しなければならない。

`ls -a`で表示される。

## 引用符

### バックスラッシュ `\`

`\`はエスケープキャラクタである。

```zsh
% echo abc\def 
abcdef
% echo abc\\def
abc\def
```

### シングルクォテーション`'`

`'`は一番強いクオテーションで、`'`で挟まれると文字列扱いされる。

```zsh
% echo *
abc append xyz
% echo "*"      
*
```

### ダブルクォテーション`"`

`$`,`'`,`\`以外をエスケープし文字列として扱う。

### バッククォート``` ` ```

``` ` ```はその中に書かれたコマンドを実行し、その結果をその位置に書き込む。

```zsh
% echo "Today is `date`"
Today is 2020年 4月30日 木曜日 23時51分48秒 JST
```

## True or False

コマンドは正しく終了すると`0(真,true)`
それ以外は`0以外(偽,false)`となる。

## コマンドセパレータ

### セミコロン`;`

1つのコマンドの区切り。
`;`の代わりに改行したのと同じ動作をする。

```zsh
% echo 3; echo 4;
3
4
```

### パイプ`|`

出力された結果を次のコマンドの入力にする。

```zsh
% echo abc | wc
       1       1       4
```

ここでwcは文字数を出力するもので「1 1 4」は1行1単語4文字を意味する。4文字になるのはabcの後に改行コードがあるから。

### アンパサンド記号`&`

バックグラウンドで実行させる。

```zsh
#makeコマンドをバックグラウンドで実行する
% make &
```

### その他

OR演算子`||`
AND演算子`&&`
などがある。

## 制御文

### if文

```zsh
if commando-list
then
    command
else
    command
fi
```

### for文

```zsh
for variable in word-list
do
    command
done
```

### while文

```zsh
while command-list
do
    command
done
```

### case文

```zsh
case string in
    pattern1)    command-list    ;;
    pattern2)    command-list    ;;
    pattern3)    command-list    ;;
             ・・・・・・
esac
```

### testコマンド

ある条件を判定し、その条件が正しいと0(true)を返し、間違っているときは1(false)を返す。

```zsh
if test -r file
then
    echo "The file exists and I can read it"
fi
```

`test -r file`の代わりに`[ -r file ]`とすることもできる。

# 終わりに

[シェルプログラミング入門2](https://qiita.com/twrcd1227/items/03310278eea64319b0e4)