Shellスクリプト

【Shell-TIps】getoptsとusageを実装してみる。

2020年5月13日

シェルには、コマンドのオプシヨンを解析したリチェックしたりするための、getoptsというコマンドが用意されています。

レビュー時にいつも思うのは、この「getOpts」を使用するエンジニアが少ないこと・・

「getOpts」コマンドは、シェルに対して「-」と"アルファベット1文字"でオプションを指定された場合、それを解析するコマンドです。オプションによって挙動を変えたい時にcase文と共に用います。

実際には習うより慣れろが正しいため、下記にサンプルを実装します。

「getOpts」コマンド

「getOptsコマンドを使うと何がうれしいの?」とよく聞かれることがあります。特にうれしいことはありませんが(笑う・・楽です

もし、シェルスクリプトの引数処理で何かの制御をおなう場合、一番初めに考えれらるのが「if」文だと思いますが、「if」文で引数を制御する場合はパラメータの順番に気を遣わなければならなくなります。

仮にバックアップ用のシェルスクリプト「backup.sh」を作成した場合、必要となる要素は「バックアップ対象」と「バックアップ格納先」になると思います。

ハードコーディング(ソースべた書き)でも良いのですが、それだと「backup.sh」が汎用的に使用できないモノになってしまうため、通常はまず引数で情報の受け渡しを考えるはずです。

if文の場合

# バックアップシェル実行形式
$ backup.sh <バックアップ対象> <バックアップ先パス

# 「backup.sh」内部の引数チェックロジック
#!/bin/sh
checkArgs() {
  if [ -f ${1} ]; then
    src=<バックアップ対象
  fi
  if [ -d ${2} ]: then
    dst=<バックアップ先パス
  fi
}

上記がその際に考えられる実行形式になると思います。

この場合、もし第一引数の<バックアップ対象>に値がはいっていなかった場合どうなるでしょう。値が空であるため、第二引数の<バックアップ先>が第一引数として実行されてしまうのです。

# バックアップシェル実行形式
$ backup.sh <バックアップ対象(空)> <バックアップ先パス

# 「backup.sh」内部の引数チェックロジック
#!/bin/sh
checkArgs() {
  if [ -f ${1} ]; then
    src=<バックアップ先パス
  fi
  if [ -d ${2} ]: then
    dst=
  fi
}

チェックが甘くて正常終了してしまった場合、あるはずのバックアップが存在しないことになってしまいます。

getOptsの場合

判り易くバックアップ対象を「-s(source)」、バックアップ先パスを「-d(destination)」としておきます。

# バックアップシェル実行形式
$ backup.sh -s <バックアップ対象> -d <バックアップ先パス

#!/bin/sh
#-s /-d オプションを指定した場合に出すメッセージを変更する
while getopts s:d: opts
do
  case $opts in
    s ) src=$OPTARG ;;
    d) dst=$OPTARG ;;
    * ) usage
       exitLog ${JOB_WR} ;;
  esac
done;

while」文の隣に「getOpts」コマンドを記述します。getoptsの次に書かなくてはならない引数は、このシェルスクリプトで処理させようとするオプションを並べたものになります。

もしそのオプションが値を必要とするものならば、その直後に「:(コロン)」を付けます。つまり「while getopts s:d: opts」となります。

:(コロン)」を付けたオプションの値は、$OPTARGと言いう変数に自動的に格納されます。よって「while」文直下の「case」文の処理では、$OPTARGに代入された値をスクリプト内の変数へ代入します。「src=$OPTARG

上記のロジックの場合、「-s(source)」、バックアップ先パスを「-d(destination)」何方でもないオプション(例えば[ r ]など)が引数と渡された場合、「case」文の「*)」でキャッチされます。

上記の例では「usage」がコールされ、処理が「exitLog」へ引き渡されます。

「Usege」関数

この「Usage」関数は、特にシェルに用意されているモノでありません。「ヒアドキュメント」を使用して、作成したシェルの実行方法や引数などを表示する自作関数です。

記述方法は簡単で、「ヒアドキュメント」を関数かしただけです。

実際に作成してみます。

usage() {

cat <<EOUSAGE
-----------------------------------------------------------------
Usage: $0 [< options >]

Options:
-b backup_target : Specifies the target file or target to backcup.
-m destination_path : Specify the backup storage directory path.

------------------------------------------------------------------
EOUSAGE
}

これだけです。「$0」は実行しているスクリプト名を表示します。つまり自分の名前です。

EOUSAGEは「End Of Usage」の略です。特に制約等はありませんので開始と終了が同じ文字列なら「EOF」でもなんでもかまいません。

このように「ヒアドキュメント」以外に、特にロジックというロジックはありません。(笑

上記「usage」は、「case」文の「*)」でキャッチされ、実行されます。つまり間違えた引数を指定してシェルを実行した場合、エラーと一緒に出力される自作ヘルプメッセージです。

「usage」の実行結果

どうでしょう? それなりに見えませんか?

「オレ(ワタシ)って意外といけるんじゃね?」と思っていただけると嬉しいです。

最後に、上記を実行したシェルスクリプトを載せておきます。

実行シェルスクリプトを作成する

本スクリプト利用により発生した利用者の損害全てに対し、いかなる責任をも負わないものとし、損害賠償をする一切の義務はないものとします。

よく読まれている記事

1

独立前は、誰もが不安でいっぱい。近い将来、フリーランスとして独立を考えている方が独立初期に躓かないために「独立前にやるべきことチェックリスト」をご紹介します。 当記事は前編となる「お金まわり編」。全て ...

2

ゲームなどのエンタメ分野での導入が進んでいるVR。言葉自体は耳にしたことがあっても、その意味を詳しく知らないという人も多いのではないでしょうか。また、次世代の新たな技術をビジネスに積極的に活用していく ...

3

フリーランスの確定申告には、青色申告と白色申告の2種類があります。いったいどちらの申告方法を選ぶべきなのでしょうか。 この記事では、青色申告と白色申告、それぞれのメリット・デメリットを把握することでベ ...

4

フリーランスの仕事場は、自宅をはじめとし、カフェや図書館、コワーキングスペースなど自由に選べます。しかし全ての場所で100%集中ができるどうかは、人それぞれです。どのような環境が自身の仕事場として快適 ...

5

フリーランスのITエンジニアとして、一番難しいのは「自己管理」と言えるでしょう。 自分の体調管理はもとより、仕事のスケジュール等すべて自分で管理します。もちろんフリーランスに有給休暇等ありませんから休 ...

-Shellスクリプト

Copyright© Beエンジニア , 2020 All Rights Reserved.