カイワレの大冒険 Third

技術的なことや他愛もないことをたまに書いてます

シェルスクリプトを書く際に気を付けていること8箇条

エンジニアという職業柄かシェルスクリプトを書くことはちょくちょくあるのですが、自分なりに気を付けていることを備忘録&自分への戒めも含めて、簡単に書いてみたいと思います。

変数は大文字

シェルスクリプト書いていれば変数の出番は至るところであるでしょう。その際、可読性を増すように、変数は大文字を使っています。

RET=`cmd1`

みたいに。好みの問題もあるでしょうが、分かりやすいので。

クオテーションは選ぶ

クオテーションにはシングルだったり、ダブルだったり色々ありますが、使い分けておいたほうがよいでしょう。

変数の展開がないようであれば、シングルクオーテーションのほうがスマートでしょうし、展開があるのならダブルクオーテーションを使えばと。

ダブルクオーテーションを使うのにも意味があって、変数は「$RET」のようにクオテーションで囲まなくても動作はたいていするのですが、

echo "${RET}"

のようにしておくことで、

スペースが入っても処理してくれるといううまーな面があります。スペースこわいお。

例外処理は忘れない

上述したcmd1ですが、そのコマンドがちゃんと正しく実行されて、エラーになっていないかはチェックしておいたほうがよいでしょう。

mysqldumpでバックアップ用のシェルを仕掛けているのに、それを捕捉できないとか、sshで何かリモートホストに対してコマンド発行してるのに、実はsshで接続できてなかったとか。

致命的になりかねないので、「$?」を使い直前のコマンドの終了ステータスを得て、それで条件分岐させておくのが無難でしょう。

また、直前のコマンドにパイプが含まれる場合は、一番最後の処理しか見てくれないので、「$?」を使う際は最初のコマンドのみをまず捕捉するか、特定のシェルに限定されるけど、「${PIPESTATUS[@]}」を使うことで解決するのがよいかなと。

改行コードに気をつける

Windowsでコード書いて、コミットとかが全くないとは言えなくて、そういうときに改行コードを意識してないと大体死にます。その辺は改行コードと「command not found」の関係について - カイワレの大冒険 Thirdに書いてます。まぁ、サーバで特定ディレクトリをバージョン管理して、Vim使えばいいんじゃねという。

実行時には「-u」をつける

/bih/sh -u test.sh

みたいな感じでやりましょうという話し。-uをつけることで、定義されていない変数を使った場合はエラーを吐くようになります。こういうのも地味に大事ですよ。

2016/05/24追記:
シェバンで以下のようにしても同じですね。

#!/bin/sh -u

「set -e」をコードの頭に書いておく

要は、

#/bin/sh
set -e

としとけということですな。ディレクトリ無いのにファイル作ろうとしたり(ディレクトリチェックしないのが悪いけども)、例外処理が甘かったり、色々あるでしょうが、簡単なチェックなら「set -e」で捕捉できるよと。まぁ、本来は一つ一つチェックして、テストしたほうがいいと思います。例外処理大事。

2016/05/24追記:
シェバンで以下のようにしても同じですね。

#!/bin/sh -e




declareを駆使する

http://www.tldp.org/LDP/abs/html/declareref.htmlから引用しますが、こんな風にdeclareを使って書ける。

declare -r var1=1
echo "var1 = $var1"   # var1 = 1
(( var1++ ))          # x.sh: line 4: var1: readonly variable

この場合のvar1は「-r」がついているので、readonlyでございます。なので、インクリメントは当然できない。コードの冒頭で宣言しておいたほうがよいですな。

「-i」を使うとintegerであるとか色々型決められるので、指定しておいたほうがいいですよ。数値で返ってくること期待しても、エラー文字が変数に入ってることとかあったりするので。

ちなみに、読み込み専用は変数定義する際に、

readonly VAL1=1

と書いてもいけますです。

テンプレート補完を使う

$HOME/.vimrcに

autocmd BufNewFile *.sh 0r $HOME/dotfiles/vim_config/templates/sh.txt

と書いておくと、「*.sh」を満たすファイルをVimで作成すると、sh.txtを読み込み、テンプレートとして使うことが可能です。

Usageだったり、Authorだったり、「#!/bih/sh」OR「#!/bih/bash」だったり、最低限のものはテンプレートとして用意しておいたほうが楽でしょうね。

終わりに

まぁ、なかなかゼロから書くこともそんないっぱいあるわけではないですし、こういうのは凝りだすとキリがないので、可能な範囲でよいでしょうが、なんだかんだいってシェルスクリプトは便利だし、出番もちょくちょくあるので、紹介してみました。
多分、一年後にはもっと違うこと書いてる気がするけど。。。

間違い・もっとよい書き方があればKenichi MASUDA (@masudaK) | Twitterまでお願いします!

P.S. 以下のサイトにはもう少し書いてある。trapとか。
www.davidpashley.com

以下のサイトは未だ読破できない。 Advanced Bash-Scripting Guide

以下の記事もおすすめです。
インフラエンジニアがアプリエンジニアに転身するにはこの3冊を勉強すれば十分だ - カイワレの大冒険 Third