2015年01月25日

bash: パラメタ展開を上手く使いこなしてif文を減らす

このエントリーをはてなブックマークに追加

if文を省略可

GitHub API v3をcurlコマンド経由でAPI呼び出しをしていると、Token有無による場合分けが、しばしば必要となる。普段は当たり前の様にbashスクリプトを活用してcurlコマンドオプションを組み立てている。そして、-n-zによる文字列テストによる場合分けをしていた。そう、今までは。

[[ -n "${GITHUB_TOKEN}" ]] && { echo "-H \"Authorization: token ${GITHUB_TOKEN}\""; }

ある日、時々シェルスクリプトを書く@unakatsuoが言う。

文字列展開のうち、+の使い方・使い処が分かった。 echo ${var:+"foo ${var}"} みたいに書くと良い。

存在は知っていたが、使わずに来た。

未開拓のパラメタ展開

man bash(1)より。

   Parameter Expansion

       ${parameter:+word}
              Use Alternate Value.  If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted.
  • parameterがnullかunsetの場合は置き換えない
  • そうでない場合は置き換える

これを上手く使うと、if文を省略して書けると言う。先述のコードを、+によるパラメタ展開を使い書き直すと、

before:

[[ -n "${GITHUB_TOKEN}" ]] && { echo "-H \"Authorization: token ${GITHUB_TOKEN}\""; }

after:

echo ${GITHUB_TOKEN:+"-H \"Authorization: token ${GITHUB_TOKEN}\""}

コードが短くなった。

おまけ:test-github-issues.sh

普段使いのスクリプトから一部を抜粋。

#!/bin/bash
#
#
set -e
set -o pipefail

function curl() {
  echo curl "${@}"
}

function github_issues() {
  curl \
   -fsSkL \
   $([[ -n "${GITHUB_TOKEN}" ]] && { echo "-H \"Authorization: token ${GITHUB_TOKEN}\""; } ) \
   "https://api.github.com/repos/${owner}/${repo}/issues"
}

function github_issues2() {
  curl \
   -fsSkL \
   ${GITHUB_TOKEN:+"-H \"Authorization: token ${GITHUB_TOKEN}\""} \
   "https://api.github.com/repos/${owner}/${repo}/issues"
}

owner=github
repo=github

GITHUB_TOKEN=     github_issues
GITHUB_TOKEN=     github_issues2

GITHUB_TOKEN=asdf github_issues
GITHUB_TOKEN=asdf github_issues2

[[ "$(GITHUB_TOKEN=     github_issues)" == "$(GITHUB_TOKEN=     github_issues2)" ]]
echo ${?}
[[ "$(GITHUB_TOKEN=asdf github_issues)" == "$(GITHUB_TOKEN=asdf github_issues2)" ]]
echo ${?}

上記スクリプトを実行すると、こうなる。

$ chmod +x ./test-github-issues.sh
$ ./test-github-issues.sh
curl -fsSkL https://api.github.com/repos/github/github/issues
curl -fsSkL https://api.github.com/repos/github/github/issues
curl -fsSkL -H "Authorization: token asdf" https://api.github.com/repos/github/github/issues
curl -fsSkL -H "Authorization: token asdf" https://api.github.com/repos/github/github/issues
0
0
  • GITHUB_TOKEN あり / なし
  • github_issuesgithub_issues2 による生成文字列

生成された文字列が改良前後で同一かどうかをテストし、同一である事を確認。

あとがき

多用し過ぎると可読性が低下しそうなので、ご利用は計画的に。




編集
@hansode at 17:00│Comments(0)TrackBack(0)bash 

トラックバックURL

コメントする

このブログにコメントするにはログインが必要です。