シェルスクリプトでハマったところ

シェルスクリプトではまった点についてまとめる。


# ■ 検索

## ● locateとfindの違い

ファイル名が分かっている場合はインデックスを参照するlocateの方が高速。

```shell-session
# インデックスの更新
sudo updatedb
locate ファイル名
```



# ■ 計算

## ● 実数の計算は"bc"コマンドを使う必要がある。

scalceで少数点以下の桁数を調整。

```shell-session
# echo "scale=2; 10 / 3" | bc
3.33
# echo "scale=3; 10 / 3" | bc
3.333
# echo "scale=4; 10 / 3" | bc
3.3333

# echo "scale=4; 0.1 / 10" | bc
.0100
```

# ■ 条件分岐 

## ● 文字列比較には=, 数値比較は"-eq"

* [文字列比較には=を使う](http://piro791.blog.so-net.ne.jp/2010-03-08)

## ● if文における [[]] と []の違いについて

* [] : testコマンドの省略系
* [[]] : []よりも多機能(条件指定に&&, ||, Pattern matching, 正規表現)


* [Bashにおける括弧類の意味](http://qiita.com/yohm13/items/3527d517768402efbcb6)

# ■ 関数

## ● 関数の戻り値に文字列を指定できない
~~return コマンドの引数に指定できる値は、1～255 の正の整数のみ~~
return コマンドの引数に指定できる値は、0～255 の整数のみ

## ● ローカル変数を使用するには、localを指定する必要がある
一般的なプログラミング言語と異なり、使用する変数はグローバル変数になる。
ローカル変数にするにはlocalを使用する必要がある。

```
func() {
  local x="local"
}

```

http://shellscript.sunone.me/function.html

# ■ shellのオプションを設定するにはsetコマンド

|オプション|内容|
|:--|:--|
|x|コマンドと引数の展開処理(デバッグ)内容を標準エラー出力|
|v|コマンドの実行行を標準エラー出力|
|n|コマンドを実行せず，構文エラーだけを確認する|
|u|未定義の変数を参照するとエラー・メッセージを表示|
|e|コマンドが0以外のステータスで終了した場合，一部の場合を除いて即座に終了する|
|f| パス名のワイルドカードによる展開（*や?）を無効にする|
|o ignoreof |CTRLキーを押しながらDキーを押しても，シェルを終了しないように設定する。exitコマンドは利用できる|

```shell-session
# xオプションを有効化
set -x

echo "test command"

# +で無効化。
set +x 
```
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230881/

# ■ 特殊記号を無効にする

## ● 関数に特殊文字を渡す

```shell-session
# パス名のワイルドカードによる展開（*や?）を無効にする
set -f
function "* * * argv"
set +f
```

## ● grepで特殊記号を無効

grep -Fを使う
```
grep -Fとは
-F ⇒ --fixed-strings
パターンではなく固定文字列での検索を行う。
```
http://togattti.hateblo.jp/entry/2014/01/19/001418


# ■ プロセスが強制停止しても、確実に処理を行いたい場合はtrapコマンド

## ● trapコマンド
実行中のプロセスに対するシグナルを検知し、指定された処理を返すコマンド

# シグナル とは
# 実行中のプロセスに対して、プロセス停止などのイベントを通知するために>送出される信号

|シグナル番号|シグナル名|通知内容|
|:-:|:-:|:-:|
|1|HUP|プロセスに再起動を通知する。|
|2|INT|プロセスに割り込みを通知する。(Ctrl+c)|
|3|QUIT|プロセスに終了を通知する。(coreを作成する)|
|9|KILL|プロセスに強制終了を通知する。|
|15|TERM|プロセスに終了を通知する。(デフォルト)|
|18|CONT|プロセスに再開を通知する。|
|19|STOP|プロセスに中断を通知する。|
|20|TSTP|プロセスにサスペンドを通知する。(Ctrl+Z)|


```shell-session
# -l シグナル一覧を表示する
# -p 指定された処理を確認できる
trap -l
trap -p

# プロセスの終了シグナル(0)を受け取った際に、コマンドを実行する
# trap "コマンド" [シグナル or  シグナル名]
trap "
    echo '`basename $0` end.'
    echo 'status is $?'
" 0
```

http://shellscript.sunone.me/signal_and_trap.html

# ■ ファイル名の取得

```shell-session
#!/bin/bash

# ファイルのフルパスを取得
# シンボリックリンクの場合は実態の取得
# $0 : 自身のファイルパス
echo $(readlink -f $0)

# -f : ファイルが存在しなくてもフルパスを返す
# -e : ファイルが存在しないときは返り値なし
echo $(readlink -f not_found_file.txt)
echo $(readlink -e not_found_filei.txt)

# ディレクトリ名の取得
echo `dirname $(readlink -f $0)`

# ファイル名の取得
echo `basename $(readlink -f $0)`
```

# ■ ２重起動防止

```shell-session
if [ $$ != `pgrep -fo $0`  ]; then
    echo "[`date '+%Y/%m/%d %T'`] warning already running."
    exit 1
fi
```
|処理|意味|
|:--|:--|
|\$0|スクリプト名|
|$$|このシェルスクリプトのプロセスID|
|pgrep |プロセス名を指定してプロセスIDを表示|
|pgrep -f|パターンにマッチしたプロセスを全て表示|
|pgrep -o|マッチしたプロセスから最古のものを表示|

http://qiita.com/TanukiTam/items/d310777b82e10e58a4db

---

# ■ ネットワークデバイスのデバイス名が変更される

ネットワークデバイスのデバイス名がeth0⇒eth1がMACアドレスの変更などにより、変更されることがある。

この場合、設定ファイルのデバイス名を書き換えることで、もとに戻せる。

```shell-session
cd /etc/udev/rules.d
view 70-persistent-net.rules
# NAMEをeth0に変更する
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
```

http://blog.livedoor.jp/itukano/archives/51865711.html
http://d.hatena.ne.jp/ktat/20090716/1247745069

# ■ 起動時にRamdiskをマウント

https://jyn.jp/linux-ramdisk/#i-3

# ■ 変数を2重展開する際はevalコマンドを使う

```shell-session
# 変数名を代入する
$ color="red"
$ VALUE_NAME="color"

# 変数名を使って、変数の値を出力
$ eval echo '$'"${VALUE_NAME}"
red
```

---

# ■ whileの外で変数を使用すると空文字になるケースがある

パイプを使うとパイプ先の処理は、別プロセス（別シェル）になるため、cat file | while ～のようなループ処理をすると、
whileが別シェルとなるので、while文中に定義した変数は、whileの外で使うと未定義のため、空文字になる。

```
cat "${file}" | while read line;
do
    value="${line}";
done
echo "${value}"
```

* https://orebibou.com/2014/11/シェルスクリプトのwhile文で代入した変数が空にな/



# ■ 参考

* [OSDN](https://linuxjm.osdn.jp)

* [シェルスクリプトリファレンス](http://shellscript.sunone.me/)

* [ShellCheck](http://masatolan.com/Webservice/shellcheck/)

* http://qiita.com/m-yamashita/items/889c116b92dc0bf4ea7d