Bashのライブラリを自作してる話

Shell Script

こんにちは、山田ハヤオです。

最近自分が作ってるBash用の小さいライブラリの紹介をします。

ホームページを作るのが面倒なので、このブログの投稿をメインページにしようと思います。

スポンサーリンク

FasBashLib

GitHub - Hayao0819/FasBashLib: A collection of small but awasome functions for Bash
A collection of small but awasome functions for Bash - GitHub - Hayao0819/FasBashLib: A collection of small but awasome functions for Bash

FasBashLibという名前で開発をおこなっています。

「Fas」はFascodeのFasから取ったのですがリポジトリは個人所有です。

Fascodeのプロジェクトでもなく完全に個人の趣味での開発です。

そして、名前にBashと入っている通りBash 5系でしか動作しません。

そのうちPOSIX互換のシェル用の関数も作りたいと考えていたりいなかったり…

ライブラリ開発とその経緯

シェルスクリプトで色々書いてると、ShellCheckによく怒られます。

そしてそれを回避するためのイディオムみたいなのがあるのですが、それを毎回記述するのが面倒で、「どんな時にも使える共通関数」をGitHub Gistに細々と上げてました。

最近、それがかなり肥大化して関数名もわかりにくいものが増えてしまったので、色々を整理する意味としっかりと関数のテストを行うという意味もこめて1つのライブラリにまとめ上げることにしました。

特徴

元々自分が継ぎ足しで作っていた関数が元で、関数名も規則性がありませんでした。

そこで1つのライブラリにまとめ上げるにあたって、色々と改善を行いました。

ライブラリを使用するユーザー視点の特徴

  • 関数が種類ごとに分かれている
  • <ライブラリ名>.<関数名>の形で定義する
  • 分割されたファイルをそのままライブラリとして使用するのは面倒なので1つのファイルにまとめ上げる「ビルド」を行う
  • ビルドされたファイルは単体なのでcurlと併用してsourceできる

ソースコード的な視点

  • ソースコードはファイルを自由に分割できる設計にする
  • ビルドの過程で余分なコメント等を削除する
  • ソースコードは全てアッパーキャメルケースで記述する
    その後、ライブラリのビルド時にスネークケースやローワーキャメルケースに変換する
  • 関数の動作を確認するテストを実装する
  • ドキュメントをソースコード内に記述する

関数が種類ごとに分かれている

関数を種類ごとに分割して、名前空間の混合を避けるようにしました。

例えばCsvに関する関数は「Csv.HogeHoge」といった感じです。

もちろんこれらの関数はビルドの過程で「csv.hoge_hoge」や「csv.hoGeHoge」のようにも変換できます。

また、分割することでビルドの段階で必要な関数を取捨選択できるできるようになっています。

例えば、Csvに関するもののみ必要な場合はビルドの段階でそれを指定することで、Csv関数とその依存関係のみがビルドされます。

<ライブラリ名>.<関数名>の形で定義する

上記と同じ話になってしまいますが、名前の混合を避けることができます。

Csv.ReadとIni.Readは別物である、といった感じです。

「ビルド」を行う

bin/Build-Single.shによって、ライブラリをまとめ上げる「ビルド」を行います。

GitHub Actionによって、常に最新のソースを利用したビルドを利用できます。

curlでsourceできる

リリースページに書いてあるコードを用いることで、ライブラリがインストールされていない環境でもスクリプトを実行できます。

オフライン環境の場合はインストールされたライブラリを利用します。

sourceでビルドされた関数をスクリプト内で使えるようにします。

#!/usr/bin/env bash
set -Eeu

# shellcheck source=/dev/null
source /dev/stdin < <(
    fasbashlib -x 2> /dev/null || curl -sL https://raw.githubusercontent.com/Hayao0819/FasBashLib/build-dev/fasbashlib.sh
)

ExampleArray=("Hello" "FasBashLib!")

IsAvailable "cowsay" || {
    Msg.Err "Please install cowsay"
    exit 1
}

PrintArray "${ExampleArray[@]}" | ForEach "cowsay" "{}"

簡単な説明

IsAvailableは外部コマンドが存在するかどうかを確認します。

PrintArrayは引数に指定された文字を1行づつ表示します。

ForEachは標準入力を1行づつコマンドの引数として渡します。(xargsのようなもの)

終わり

まだまだ発展途上で仕様も安定していませんが、少しずつ完成度を高めていこうと思っています。


これより下はプロジェクトのドキュメント的なものです。


ドキュメント

FasBashLib/docs at build-0.2.x · Hayao0819/FasBashLib
A collection of small but awasome functions for Bash - FasBashLib/docs at build-0.2.x · Hayao0819/FasBashLib

ソースコードより生成された最新のドキュメントを読むことができます。

スクリプト内で使う

リリースページのfasbashlib.shをダウンロードするか、リリースページのコードをコピペして関数をsourceします。

ビルド

全部コミコミでビルドする

リポジトリをclone後、以下を実行します。

make

ライブラリを選ぶ

ライブラリの一覧から、ビルドしたいものを選びます。

./bin/List.sh

選んだら、次のコマンドでビルドします。

./bin/Build-Single.sh [Lib1] [Lib2]...

スネークケース、ローワーキャメルケースの場合は引数に-sname-lowerを追加してください。

ドキュメント終わり

ドキュメントのミスや古い情報があれば、Issueの作成をお願いします。

更新履歴

2022/05/01 記事作成

コメント

タイトルとURLをコピーしました