はじめに
シェル環境で作業することの多いみなさんは、シェルスクリプトのパッケージ管理ツールが欲しいと思ったことはあるでしょうか?
私はあります。一時期その欲求が高まって、つい自作してしまったほどです。1
本稿では、最近見つけたシェルスクリプトのパッケージ管理ツールを1つ紹介します。
こちらです:
「basher」という名前で、一見Bash専用に見えますが、実はZshとfishにも対応しているそうです。
Even though it is called basher, it also works with zsh and fish.
私自身、BashとZshで動作を確認しており、これから常用していく予定です。
中身は完全にシェルスクリプトで実装されています。
機能概要
READMEやコマンドのヘルプをざっと見たところ、以下のような機能があります。
- GitHub or 任意のサイトからパッケージを取得してインストール
- リモートからの取得手段は
git clone
のみだと思います - sshスキームにも対応しているようです
- リモートからの取得手段は
- ファイルシステム内のパッケージをインストール
- インストールしたパッケージ内の実行可能ファイルにPATHを通す
-
include
関数によって、インストールしたパッケージ内の任意のシェルスクリプトを読み込む(source
or.
相当) - Bash / Zshの場合、パッケージの設定によって、completionファイルを適切に配置し、初期化処理の中で読み込む
- インストールしたパッケージの一覧、更新、削除
以下では、インストール手順や使い方の説明をします。
インストール方法
basherの取得
git clone https://github.com/basherpm/basher.git ~/.basher
シェル環境に読み込む
2020-05-22現在は、READMEとは少しコマンドを変える必要があります。2
Bashの場合、以下をbashrcに加えます:
export PATH="$HOME/.basher/bin:$PATH"
eval "$(basher init - bash)"
Zshの場合、以下をzshrcに加えます:
export PATH="$HOME/.basher/bin:$PATH"
eval "$(basher init - zsh)"
使い方
パッケージのインストール
GitHubにホストされているリポジトリであれば、 basher install <account>/<repository>
の形式でインストールできます。
例:
basher install sstephenson/bats
これにより、batsリポジトリが ~/.basher/cellar/packages/
配下にcloneされ、以下のように bats
コマンドが ~/.basher/cellar/bin/bats
にsymlinkされます。
$ ls -l ~/.basher/cellar/bin/
lrwxrwxrwx 1 progrhyme progrhyme 62 5月 22 23:37 bats -> /home/progrhyme/.basher/cellar/packages/sstephenson/bats/bin/bats
これで bats
コマンドがPATHに入った状態で使えるようになりました。
ソースも追ってみたところ、basherはデフォルトでパッケージの bin/
ディレクトリか、 bin/
ディレクトリが無ければルートディレクトリ直下から実行可能ファイルを探してsymlinkを作成してくれるようです。
include関数でシェルスクリプトを読み込む
機能概要で説明したように、basherで実装されている include
関数を使うことで、インストールしたパッケージの任意のシェルスクリプトを読み込むことができます。
構文としては、 include <package> <path>
のようになります。
先に例としてインストールしたbatsは、シェル環境に読み込んで使うタイプのツールではないので、ここでは手前味噌ですが、拙作のbash-loggerというユーティリティをインストールして使ってみます。
$ basher install progrhyme/bash-logger
Cloning into '/home/progrhyme/.basher/cellar/packages/progrhyme/bash-logger'...
: # 略
インストールしたbash-loggerに含まれる logger.bashrc
を include
して、定義されているロガー関数を使ってみます。
$ include progrhyme/bash-logger logger.bashrc
$ log.warn "blah blah blah"
2020-05-23 00:12:11 [WARN] blah blah blah
このように、パッケージのシェルスクリプトを読み込んで、定義されている関数等を利用することができます。
ファイルシステム内のパッケージをインストール
basher link
コマンドを使うと、ローカルのシェルスクリプトをパッケージとして擬似的にインストールすることができます。
この機能は、特にシェルスクリプトによるツール開発をよく行う人に便利だと思います。
あるいは、リポジトリの構造がbasherに対応していないときに、特定のディレクトリをパッケージとしてインストールしたり、手元で後述のpackage.shを配置してインストールするようなユースケースが考えられます。
私の場合、いくつか自作のシェルスクリプト製のツールがあるので、動作確認時にこの機能を使いました。
basher link path/to/repos/shove progrhyme/shove
注意点として、パッケージ名として与える文字列(上では progrhyme/shove
)は <account>/<repository>
の形式でないとエラーになります。(何度か気づかずに軽くハマりました。)
挙動としては、下のようにsymlinkされる形になります。
ので、実体を変更したら、インストールされたパッケージ側にも即座に反映されることになります。
$ ls -l ~/.basher/cellar/packages/progrhyme/
lrwxrwxrwx 1 progrhyme progrhyme 27 5月 23 00:29 shove -> /path/to/repos/shove
パッケージにpackage.shを配置する
パッケージのルートディレクトリ直下に package.sh
というファイルを配置しておくことで、該当パッケージをインストールする際の挙動をカスタマイズすることができます。
README.mdのままですが、下がサンプルとなります:
BINS=folder/file1:folder/file2.sh
DEPS=user1/repo1:user2/repo2
BASH_COMPLETIONS=completions/package
ZSH_COMPLETIONS=completions/_package
それぞれの変数では、次の内容を指定することができます:
-
BINS
... 実行可能ファイルとして配置するファイルのパッケージ内のパス -
DEPS
... 当該パッケージが依存するパッケージ。同時にインストールされる -
BASH_COMPLETIONS
... bash-completionとして配置されるファイルのパッケージ内のパス -
ZSH_COMPLETIONS
... zsh-completionとして配置されるファイルのパッケージ内のパス
いずれも :
を区切り文字として複数指定することができます。
この機能を試したところ、次の制限事項があるようです:
-
DEPS
で指定したパッケージは、当該パッケージをアンインストールしても同時にアンインストールされることはない。
制限事項
macOSでcoreutilsが必要
2020-05-24現在、 basher link
が動作しませんでした。
realpath(1)またはGNU readlinkがないと動かないようです。3
いずれも brew install coreutils
でインストールされます。
realpathがあればそちらが優先して使われるので、GNU readlinkを使うことはないでしょう。
終わりに
以上、basherの機能と使い方をざっと紹介しました。
basherは仕組みがわかりやすく、必要十分な機能が揃っているように思います。
basherを使ってシェルスクリプト製ツールを管理すると、gitのsubmoduleで管理するよりは楽で、野良でシェルスクリプトを入れるよりも見通しがよくて便利なのではないかと思います。
また、 include
が便利なので、ひょっとしたらHomebrewなどでインストールしているツールも、シェルスクリプトのものはbasherに移行する価値があるかもしれません。
私が4年前にパッケージ管理ツールを自作したときは、basherの存在に気づかなかったのですが、実は6年前には下のブログ記事が公開されていました。
もし当時、気づいていれば、ツールを自作しようとは思わなかったかもしれません。
参考
- A Package Manager For Shell Scripts - Juan Ibiapina ... 作者によるbasherの紹介ブログ
脚注
-
4年ぐらい前に作って、ずっと自分でドッグフーディングしていました。(参考)"clenv" というシェルスクリプトのパッケージ管理ツールのようなものを作った - weblog of key_amb。最近、basherに乗り換えつつあります。 ↩
-
https://github.com/basherpm/basher/pull/77 で変更されたそうで、まだREADMEが追従してないようです。些細な修正ですが、PRしてみました。 ↩