LoginSignup
54
31

More than 5 years have passed since last update.

シェルスクリプトを自己文章化する

Last updated at Posted at 2017-10-27

Friday I/O
株式会社ワムウでは、毎週金曜日は 興味がある事柄に取り組み、その成果を何らかの形でアウトプットする日 としています。

はじめに

Dockerを使用した開発では docke-run , docker-compose run のようなコマンドと引数の数が複雑になりがちです。
そのために皆さん都度ラッパースクリプトを記述し解決を図ることでしょう。

しかし時間が経った後に、そのスクリプトを走らせようとした時はしばしばラッパースクリプトのサブコマンドを忘れていたりするものです。

Usage を丁寧に記述することで、この問題は解決することにはなりますが Usageを都度メンテナンスする必要がある という別の問題が発生します。

これらの問題を解決するために シェルスクリプトを自己文章化する という解決策を提示します。

実現方法

下記のように Usage をファイルの先頭にまとめて記述するのではなく、各サブコマンド関数名の後ろに ## を付けてコメントを記述します。

version() ## Show version
{
    echo "$(basename ${0}) version 0.0.1 "
}    

start() ## Start some program
{
    echo "COMMAND START"
}

stop() ## Stop some program
{
    echo "COMMAND STOP"
}

restart() ## Stop and Restart
{
    stop && start
}

このようなサブコマンドが記述されたスクリプトに、Usageをこのように記述します。

usage() ## Show this message
{
    echo '\033[33mUsage:\033[m'
    echo " $0 [command]"
    echo

    echo '\033[33mCommands:\033[m'
    grep -E '^(function\s+)?\w+\(\)\s+\{?\s*##' $0 | sed -e 's/{//;s/ \{1,\}/ /g;s/function //;s/() ## /<>/' | awk -F '<>' '{printf " \033[36m%-20s\033[0m %s\n", $1, $2}'
}

後は各関数を引数として受け取りサブコマンド化するだけです。

ACTION="$1"

if [ -n "$(type -t $ACTION)" ] && [ "$(type -t $ACTION)" = function ]; then
     $ACTION $@
 else
    echo "\033[31m[ERROR] Invalid command \033[m'${1}'"
    echo
    usage
    exit 1
fi

実行例

example.gif

全コード

#!/bin/sh

ACTION="$1"

version() ## Show version
{
    echo "$(basename ${0}) version 0.0.1 "
}    

start() ## Start some program
{
    echo "COMMAND START"
}

stop() ## Stop some program
{
    echo "COMMAND STOP"
}

restart() ## Stop and Restart
{
    stop && start
}

usage() ## Show this message
{
    echo '\033[33mUsage:\033[m'
    echo " $0 [command]"
    echo

    echo '\033[33mCommands:\033[m'
    grep -E '^(function\s+)?\w+\(\)\s+\{?\s*##' $0 | sed -e 's/{//;s/ \{1,\}/ /g;s/function //;s/() ## /<>/' | awk -F '<>' '{printf " \033[36m%-20s\033[0m %s\n", $1, $2}'
}

if [ -n "$(type -t $ACTION)" ] && [ "$(type -t $ACTION)" = function ]; then
     $ACTION $@
 else
    echo "\033[31m[ERROR] Invalid command \033[m'${1}'"
    echo
    usage
    exit 1
fi

サブコマンドを case 文で処理したい場合などは grep の正規表現を変更するとよいでしょう。

参考

54
31
0

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
54
31