「ShellCheck」を使って、メンテナンス性の高いシェルスクリプトを実装する

ShellCheckとは

ShellCheckは、シェルスクリプトの静的解析ツールで、マズい書き方をしてると怒ってくれるLinterだ。

たとえば、example.sh という下記のシェルスクリプトがあるとしよう。

echo $0

これをShellCheckでチェックすると、こんな警告を出してくれる。

In example.sh line 1:
echo $0
^-- SC2148: Tips depend on target shell and yours is unknown. Add a shebang.
     ^-- SC2086: Double quote to prevent globbing and word splitting.

この例では、「shebangを書け」「変数使うときはダブルクォート使え」的な指摘をしてくれる。

続きを読む

「cli-highlight」で無味乾燥なターミナル表示をカラフルに

cli-highlightとは

cli-highlightはターミナルでもエディタのように、シンタックスハイライトをしてくれるツールだ。

無味乾燥なターミナルがとっても見やすくなる。

Before

なんの面白みもない表示。

f:id:tmknom:20180930183031p:plain

After

とってもカラフルで見やすい!

f:id:tmknom:20180930183044p:plain

続きを読む

GitHubのWikiをマークダウン形式で取得する

背景

ときどき、GitHubリポジトリで、ツールの使い方などがバージョン管理されたファイルではなく、Wikiに書かれていることがある。

ブラウザから参照することも可能だが、このWikiで書かれたテキストをマークダウンで取得したくなるときがまれによくある。

GitHub API

とりあえず、GitHub APIでなにか提供されていないか調べるのが王道だろう。

で、調べてみたのだが、なんとWikiに関するAPIが一切存在しない。おぉ、マジか。

curl

じゃあ、curlで適当なURL叩いたら取れないかと思い試行錯誤したら取れた。

curl -s https://raw.githubusercontent.com/wiki/<user>/<repo_name>/<title>.md

たとえば、jqコマンドのWikiのページを取得するときはこんな感じ。

curl -s https://raw.githubusercontent.com/wiki/stedolan/jq/Home.md

タイトルに空白が含まれる場合は、ハイフンで置換すればいい。たとえば、Advanced Topicsのページはこうなる。

curl -s https://raw.githubusercontent.com/wiki/stedolan/jq/Advanced-Topics.md

git clone

余談だが、Wikiの内容はgit cloneすることができる。

git clone git@github.com:<user>/<repo_name>.wiki.git

さきほど同様、jqコマンドのWikiを例にするとこんな感じ。

git clone git@github.com:stedolan/jq.wiki.git

どういうときに必要になるのか分からないが、何かのときに使えるかもしれない。

雑にシェルスクリプトのみを一覧取得するコマンド

ファイル名に拡張子 .sh が付いていれば見つけるのは簡単だが、拡張子なしのファイルも見つけたかったので、試行錯誤をメモ。

最初に結論

$ grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1 | grep -v .git

試行錯誤

shebangで検索

$ grep '^#!' -rl .

行頭が #! ではじまるファイルを探している。

あんまりこれで困らないと思うが、欠点も存在する。一行目ではなく、ファイルの途中に #! があっても拾ってしまうのだ。

一行目のみに絞り込む

$ grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1

最初のgrepで行番号も出力している。たとえば、こんな感じで出力される。

$ grep '^#!' -rn .
./install:1:#!/bin/sh
./README.md:33:#!/bin/sh
./hooks/build:1:#!/bin/bash

そして、 :1:#!grepかけて、一行目に含まれているファイル一覧に絞り込む。

$ grep '^#!' -rn . | grep ':1:#!'
./install:1:#!/bin/sh
./hooks/build:1:#!/bin/bash

最後にファイル名だけ取り出す。

$ grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1
./install
./hooks/build

.gitを除外

$ grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1 | grep -v .git

git 管理してるディレクトリ配下で実行すると .git ディレクトリ内も検索してしまう。そこで、単純に -v オプションで .git ディレクトリ配下を除外する。

おまけ:Makefile内で使う

最初、Makefileで定義するにあたって、普通にshell関数内で実行して、その結果を変数に格納していたが、なぜかshell関数は、実行結果の改行を空白に置換してしまって困った。

仕方ないのでマクロ定義して、それを呼び出すことにした。

define list_shellscript
    grep '^#!' -rn . | grep ':1:#!' | cut -d: -f1 | grep -v .git
endef

で、使うときはこんな感じ。

$(call list_shellscript)

xargsと組み合わせるときも、こんな感じで書ける。

$(call list_shellscript) | xargs -I {} echo {}

Makefileはフツーのシェルスクリプトとは異なる挙動をするので、なかなかにムズイ。

「VPC Flow Logs」をAWSマネジメントコンソールで設定する

VPC Flow Logs

概要

VPC Flow LogsはVPC内のIPトラフィックをキャプチャして、CloudWatch Logsに保存してくれる機能である。VPC Flow Logsでは、下記の単位でキャプチャすることが可能である。

本記事では、サブネット単位でキャプチャする例を提示する。VPC Flow Logsの詳細は公式ドキュメントを参照すること。

構築手順

VPC Flow Logsを使えるようにするには、大雑把に2つのことをやる。

  • IAMロールの定義
  • VPC Flow Logsの作成
続きを読む

ECS初回構築時に自動作成されるIAMロール「AWSServiceRoleForECS」とTerraformでの予期せぬ挙動

AWSServiceRoleForECSとは

ECSを作成すると、勝手に作られるIAMロール。Terraformでaws_ecs_clusterリソースを作ったときにも自動作成される。Service-Linked Rolesというヤツの一種らしい。

公式ドキュメントから、AWSServiceRoleForECSについての説明を引用する。

Amazon Elastic Container Service では、AWS Identity and Access Management (IAM) の「サービスにリンクされたロール」を使用します。

 

ほとんどの状況では、サービスにリンクされたロールを手動で作成する必要はありません。たとえば、新しいクラスターを作成する (たとえば、Amazon ECS の初回実行、クラスターの作成ウィザード、AWS CLI または SDK) か、AWS マネジメントコンソールでサービスを作成または更新するときに、存在しない場合は Amazon ECS によりサービスにリンクされたロールが作成されます。

すごくざっくり言えば、このIAMロールは「ECSをいい感じに動かしてくれる君」である。

続きを読む

「ECR」をAWSマネジメントコンソールから作成する

ECR

ECR(Elastic Container Registry)とは、AWSのDockerレジストリサービスである。Dockerイメージをプライベートに管理し、IAMによるアクセス制御も可能である。 詳細は公式ドキュメントを参照すること。

ECRでは、Dockerイメージごとに、リポジトリを作成するだけで簡単にDockerイメージをプッシュまたはプルすることができるようになる。

続きを読む