2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

日頃心掛けたいシェルスクリプトの治安維持

2
Posted at

気が向いたので、久しぶりに執筆してみました。

最近、とある案件で初めてそこそこ本格的にシェルスクリプトを書いたのですが、今までバッチしか知らなかった僕からして見たら「なにこれOS付属のくせにガチのプログラミング言語じゃん!」となり、ちょっとしたマイブームが来ています!

そこで色々と感じたことをメモっていきます。

治安維持は必要

シェルスクリプトはかなり万能ですが、他のプログラミング言語と比較して曖昧な表記でも許されてしまう、という点は場合によって諸刃の剣だと感じました。

つまり、自分である程度の自治をしないと、後で見返したときに苦労することになる、ということです。

施策

初期設定

Example
set -uC ignoreeof

setは、コンテキスト内でのスクリプトエンジンの挙動を設定/確認するコマンドです。

サンプルに記載されているオプションは次の通りです。

-u

いわゆる厳格モードす。
未宣言の変数を使用禁止にします。

-C

リダイレクト(>)でのファイルの上書きを禁止します。
なお、追記>>はOKです。

ファイルを上書きする場合はrm && touchのように、処理を明示的に記述します。

ignoreeof

Ctrl+Dが入力されてもスクリプトが終了しないようにします。

その他

他にも、コマンド終了コードが0以外(異常終了)なら即座にスクリプトを中断する-eオプションや、標準エラー出力を表示する-xオプションなどありますが、いずれも必要な場合とそうでない場合があると思いますので、サンプルには記載しませんでした。

なお、これらの設定はシェルスクリプトの1行目に#!/bin/bashのような記述をする、いわゆる "shebang" でも同様に行えます。

しかし、これは個人的な意見ですが、コメント部分に実行されるコードが存在するって何か気持ち悪くありませんか...?

なのでshebangは使用せずsetコマンドを使用したほうが良いと考えます。

変数

Example
declare -r foo="bar"

for _path in "/path/to/*"
do
    echo ${_path}
done
unset _path

read _hoge
declare -r hoge="/path/to/${_hoge}"
unset _hoge

宣言

シェルスクリプトは、他言語でのvarのような変数宣言句なしに唐突に変数宣言できますが、ちゃんとdeclareという変数宣言コマンドが存在します。

declareは非常に優秀で、関数内で宣言すれば自動的にローカルスコープになりますし、定数は-rオプションを付与すれば読み取り専用(readonlyコマンド相当)になります。

他にも-aオプションで配列を宣言できたりと、使わない手はありません。

なによりdeclareで明示的に変数宣言することにより、これは変数だと判別しやすくなります。

どんな変数でも、宣言する際はdeclareコマンドで宣言しましょう。

また、他言語と同様に上書き可能な変数はなるべく減らし、できるだけ定数(-r)として宣言するよう心がけましょう。

解放

readforといったコマンドで宣言する局所的変数は、入力バリデーションやループが終了したら使わなくなるケースがほとんどです。

特に注意したいのがforの変数で、ループ内でしか使用しないにもかかわらずグローバルスコープとなっており、変数名を使い回そうとすると多重定義となり、次回使用時まで不要なデータが残ってしまいます。

なので、ループが終了したら必ずunsetで解放しましょう。
readも同様に、バリデーションなどの処理が完了したらdeclareで宣言した変数(定数)に移し替えましょう。

呼出

シェルスクリプトは変数名に$を付与して変数を呼び出せますが、更にブレースで囲う記法(${})も用意されています。

詳細は割愛しますが、シェルスクリプトのブレースには他にも様々な機能があり、そのうちブレースの前に$を付与したものが変数呼出の機能、ということです。

ブレース変数呼出には、変数名の前に#を付与することで文字数を調べられたり、変数名の後に#を付与することで内容を展開できたり、かなり高度な処理を簡単に行えます。

何より、いきなり$fooが現れるより${foo}のほうが読みやすいと思います。

なので、変数呼出は必ずブレース記法を使用するようにしましょう。

文字列

Example
echo "hogefuga"

ダブルクォーテーション

シェルスクリプトは、特に何も囲わずベタ書きすれば全て文字列の扱いになりますが、他言語と同様にダブルクォーテーションで囲う記法("")も存在します。

昔ながらのダブルクォーテーションの用途といえば、文字列内に空白が存在する場合に用いられてきました。

しかし、もちろん空白なんて存在しなくても使用して問題ありません。
それどころか、積極的に使用すべきです。

これは特に見やすさの面で関わってくると思いますが、ダブルクォーテーションで囲うとエディタのシンタックスハイライトが効き、圧倒的に読みやすくなります。

なので、文字列は必ずダブルクォーテーションで囲うようにしましょう。

まとめ

自治しながら書いていけば、かなり有用な言語だと思いました。
OSと密接なので、そういう操作をする場合は重宝するかと思います。

しかし、治安維持をサボり続けるとそこは魔境に...

今後、他にも治安維持に役立てそうな知見を得たら追記していきます!!

2
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?