tjinjin's blog

さらなる高みに1nmずつ近づくブログ

シェルスクリプト書くときにオプションを渡したくなった

About

最近AWSAPIをよく触っているわけですが、RubyなりPythonなりGoなりで書くことがあるとはいえやっぱりシェルが一番気楽と思ってしまう人間なのです。そういうときに困るのがオプションの渡し方でいろいろググったらこれだというのが見つかったので紹介します。

やりたいこと

サンプルとしてTargerGroupのarnを取得するスクリプトを作ってみます。

$ aws elbv2 --profile hoge --region ap-northeast-1 describe-target-groups | jq -r '.TargetGroups[] | select(.LoadBalancerArns != []) | .TargetGroupArn'

このスクリプトをそのままファイルに埋めてしまうとこんな感じです。

#!/bin/bash

AWS_PROFILE=hoge
AWS_REGION=ap-northeast-1

# ALBに紐付いているTargetGroupのArnを抽出
aws elbv2 --profile $AWS_PROFILE --region $AWS_REGION describe-target-groups | jq -r '.TargetGroups[] | select(.LoadBalancerArns != []) | .TargetGroupArn'

こんなんでもいいんですがいちいちファイルを開いて設定書き換えるのもダルい。ということでoption parserを用意します。

option parserを作る

いろいろググッた結果これでいいやとなりました。

#!/bin/bash -x

# for Mac, use gnu-getopt.
OPTS=`getopt -o p:r: --long profile:,region: -n 'parse-options' -- "$@"`

if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi

# 自分が使う範囲では不要そう?
eval set -- "$OPTS"

AWS_PROFILE="default"
AWS_REGION="ap-northeast-1"

while true; do
  case "$1" in
    -p | --profile ) AWS_PROFILE="$2"; shift ; shift ;;
    -r | --region ) AWS_REGION="$2"; shift; shift ;;
    -- ) shift; break ;;
    * ) break ;;
  esac
done

上記のようなファイルを用意しておいておくとsourceで読み込むようにすれば楽です。getoptの仕様がOSによって変わるのでそこだけ注意です。evalの行は良くわかってない。変数

#!/bin/bash

. ../aws/option_parser.sh


# ALBに紐付いているTargetGroupのArnを抽出
aws elbv2 --profile $AWS_PROFILE --region $AWS_REGION describe-target-groups | jq -r '.TargetGroups[] | select(.LoadBalancerArns != []) | .TargetGroupArn'

こうしておくと下記のように実行できます。

./print_tg_arns.sh
./print_tg_arns.sh --profile hoge --region ap-northeast-1
./print_tg_arns.sh -r us-west-2 -p hoge

おお、便利。awscliと似たようなオプションを使えるのがいいですね。複雑にするならRubyとかで書いたほうがいい気がするので、このくらいで留めるのが便利そうっていう感じです。他におすすめあれば教えて下さい!シェルスクリプトネタでした。

参考リンク