7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

シェルスクリプトのパッケージマネージャー「basher」の機能概要と使い方

Last updated at Posted at 2020-05-22

はじめに

シェル環境で作業することの多いみなさんは、シェルスクリプトのパッケージ管理ツールが欲しいと思ったことはあるでしょうか?
私はあります。一時期その欲求が高まって、つい自作してしまったほどです。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に加えます:

bashrc
export PATH="$HOME/.basher/bin:$PATH"
eval "$(basher init - bash)"

Zshの場合、以下をzshrcに加えます:

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.bashrcinclude して、定義されているロガー関数を使ってみます。

$ 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のままですが、下がサンプルとなります:

package.sh
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年前には下のブログ記事が公開されていました。
もし当時、気づいていれば、ツールを自作しようとは思わなかったかもしれません。

参考

脚注

  1. 4年ぐらい前に作って、ずっと自分でドッグフーディングしていました。(参考)"clenv" というシェルスクリプトのパッケージ管理ツールのようなものを作った - weblog of key_amb。最近、basherに乗り換えつつあります。

  2. https://github.com/basherpm/basher/pull/77 で変更されたそうで、まだREADMEが追従してないようです。些細な修正ですが、PRしてみました

  3. こちらも修正PRを送っています。

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?