Shell Scriptの基本

Shell Scriptを自学した際のメモ


##ターミナルでShellScriptのファイルを作成する（Mac）
「cd」コマンドを用いて所定のディレクトリに移動する。
「vim ファイル名.sh」と入力。
すると、.shファイルが作成された上、Vim（テキストエディタ）が起動する。


##Vimの使い方
escキー    →　ノーマルモード
iキー        →   入力（Insert）モード…中身をいじれる
:キー　　  →　コマンドモード…保存や終了など 
vキー　　 →　ヴィジュアルモード…選択ができるようになる

コマンドモード時のコマンド
　「:w」保存
　「:q」終了
　「:wq」保存して終了


##基本
　文頭に「#!/bin/bash」
　
　ターミナル上で「chmod +x ファイル名」で実行権限を付与してから使う。
　「./ファイル名」で実行

　「# 」でコメントアウト
　「echo ”文字列”」で文字出力

　「`date`」で日付を扱う


##変数
　「変数名=値」で宣言。
　　　　※「＝」の両端にスペースはつけない
「\\$変数名」もしくは「\\${変数名}」で使用。
　　文字列の連結は「\\$変数名$変数名」で行う。

　　文字列の扱い「"\\$変数名"」と「'\\$変数名'」の違い。
	　「"\\$変数名"」（ダブルクォート）…変数の中身が展開される。
	　「'\\$変数名'」（シングルクォート）…変数の中身が展開されない。
		ex) s=“string”のとき
			echo “\\$s” →実行→　string
			echo '\\$s' →実行→　$s
　　　　　
	「readonly」で値の変更を不可にし、定数として扱う。
　　　「readonly s=“string”」のように宣言する。

##計算

「\`expr 3 + 5\`」のように「｀」（バッククォート）と「expr」の宣言を用いて行う。
		 ※計算記号（ + や - ）の両端にスペースを入力する必要がある。
			→入れないと単なる文字列として認識される。
　　　掛け算の時だけ「\*」を用いる。
	　　また、計算の順序を示す「（）」の前にも「\」を用いる。
		ex) (3+15)*4を扱う時
			echo  \`expr \(3 + 15 \) \* 4\`   となる。

##配列
「配列名＝(要素1 要素2 要素3)」のように宣言する。
	扱う時は「${配列名[添字]}」と記述する。
	
```
		ex) kisuu=(1 3 5 7 9 )
			echo ${kisuu[2]} 
```
→実行→　「5」
「\\$\{配列名[@]\}」で全ての要素を扱える。
「\\$\{\#配列名[@]\}」で配列の要素数を表示する。

要素を変更する場合は
	「配列名[添字]=要素」のように添字を指定して、中身を代入する。
	
要素を追加する場合は
	「配列名+=(要素 要素)」のように「+=」を用いて追加する。


##条件式の評価

一般的には「true」「false」で表す。
	Unixコマンドでは「正常終了したか」という表現をする。正常に終了した場合は「0」。
	「test」コマンドを用いる。「test 数式; echo$?」　//「$?」は直前の処理が正常に終了したら「0」そうでないならそれ以外を返す。
		ex) test 1 -eq 2 ; echo $? //「-eq」は等号を表す。
			→　実行　→　「1」 //「1 = 2」は成り立たないので「0」以外を返す。
			
		条件式一覧（数値）
		「-eq」 等号　(equal)
		「-ne」 不等号　(not equal)
		「-gt」 〜より大きい　「>」　(greater than)
		「-ge」 〜以上　「>=」　(greater equal)
		「-lt」 〜より小さい「<」　(lesser than)
		「-le」 〜以下　「<=」　(lesser equal)

		条件式一覧（文字列）
		「=」 等号
		「=!」 不等号

		条件式一覧（ファイル）
		「-nt」 〜より新しい　(newer than)
		「-ot」 〜より古い　(older than)
		「-e」 ファイルが存在するのか　(exist)
		「-d」 ディレクトリ（フォルダ）であるか　(directory)

		論理演算子
		「-a」 かつ　(and)
		「-o」 または　(or)
		「!」どちらでもない　(not)
		

##条件分岐（if文）
```
	if test 数式
	then
	　	処理
	fi
```
のように記述する。
もしくは

```
	if [ 数式 ]
	then
	　	処理
	fi
```

else文に関しては下のように記述する。

```
if test 数式
	then
	　	処理
	else
		処理
	fi

```

「elif」を用いて条件を増やす。

```
if test 数式
	then
	　	処理
	elif test 数式
	　then
		処理
	else
		処理
	fi
```

##条件分岐（case文）
```

case 引数　in
	条件1)
	 処理
	 ;;
	条件2)
	 処理
	 ;;
	*)
	 処理
	 ;; 
esac

```

「*)」は全ての条件に当てはまらない時。

例

```


#!/bin/bash

signal="red"

case $signal in
  "red")
   echo "stop!"
  ;;
  "yellow")
   echo "caution!"
  ;;
  "green")
   echo "go!"
  ;;
  *)
   echo "break"
  ;;
esac                                                                               
                                                                               
                                                                                                                                    
```

##ループ処理（while）
```
while [ 数式　]
do
	処理
done
```

例　1~10まで表示する。

```
#!/bin/bash

i=0
while [ $i -lt 10 ]
do
 i=`expr $i + 1`
 echo $i
done
```

######無限ループ
「while : 」で上限を規定しないループを行える。
その際は、if文を用いてループからの除外や終了を規定する。
「continue」 除外
「break」　終了

例　10を上限としたループで,3を除外する。

```
#!/bin/bash

i=0
while :
do
 i=`expr $i + 1`
  if [ $i -eq 3 ]; then
        continue
  fi

 if [ $i -gt 10 ]; then
        break
 fi

 echo $i
done

```

##ループ処理（for）

例　1~6まで数字を出力する

```
for i in 1 2 3 4 5 6
do
 echo $i
done
```

例　配列「a」の中身を全て出力する

```
#!/bin/bash

a=(1 2 3 4 5 )
for i in ${a[@]}
do
 echo $i
done

```

「seq」を用いて初期値と上限を設定することもできる。「\`seq 初期値　上限値\`」
例　1~100まで出力する

```
#!/bin/bash

for i in i `seq 1 100`
do
 echo $i
done
```

##コマンド引数
実行時にファイル名の後ろに記述することで引数を持たせることができる。
「./ファイル名　引数1　引数2」

これらをShellScriptの側では
「\\$1」「\\$2」と記述しそれぞれ1番目の引数、2番目の引数というふうに扱える。また「\\$0」はファイルそのものを表す。
他には「\\$@」（全ての引数）や「\\$#」（引数の数）などがある。

##readコマンド
入力されたコマンドによって異なる内容を返すコマンド。
whileの無限ループの中で行う。

例　入力したコマンドを「key」というread変数に入れて出力する。「end」と入力されたら終了する。

```
#!/bin/bash

while :
do
 read key
 echo "you pressed $key"
  if [ $key = "end" ]; then
   break
  fi
done
```

##selectコマンド
選択しを作り、その結果によってそれぞれ異なった内容を返す。

例　

```
#!/bin/bash

while :
do
 read key
 echo "you pressed $key"
  if [ $key = "end" ]; then
   break
  fi
done

select menu in beef fish
do
 echo "your lunch is $menu"
 break;
done

```

ターミナルで実行すると、

```
1) beef
2) fish
#?
```

のようにコマンドを用意してくれる。
「2」を入力してEnterキーを押すと

```
1) beef
2) fish
#? 2
your lunch is fish
```

と返してくれる

##txtファイルを読み込む
「while read line」を使う。

```
#!/bin/bash

i=1
while read line
 do
  echo "$i: $line"
  i=`expr $i + 1`
done <$1
~           
```

行数を表示させるために変数「i」を使った。
変数「line」にはtxtファイルから読み込んでいた内容が入る。
またコマンド引数の「$1」を使い、実行時に引数としてtxtファイル与えておく。

```
./test.sh text.txt
```

##関数
関数の宣言は、

```
function 関数名(){
	処理
}
```
で行う。「function」は省略可能。

呼び出すときは

```
関数名
```

だけで「()」などは不要。
引数を与えて実行するときはスペースを空けてから記述する

例

```
#!/bin/bash

hello (){
        echo "hello! $1"
}

hello Bob
```

##local変数
関数内で通常通りに宣言した変数はどこからでも参照できる。
変数のスコープを関数の中に届けたい場合は頭に「local」をつけて宣言する。

```
local i=13
```