yum や apt コマンドをラップする「pmw」コマンドを作った
僕は CentOS 歴が長いので、Ubuntu の apt コマンドに慣れず、ついつい yum コマンドの要領でコマンドを叩いてしまう。また、Windows の Git SDK に同梱される pacman は全くオプションが覚えられないでいる。
こうしたパッケージ管理ツールのラッパーコマンドを作ってみたら楽になるんじゃないか、と思い、作ってみた。その名も pmw : Package Manager Wrapper。
目次
ツールの在り処
pmw は以下よりダウンロードできる。
特徴
pmw は、対応しているパッケージ管理ツールのサブコマンドを特定し、適切なコマンドを構築・実行できる。
対応しているパッケージ管理ツールは以下のとおり。
dnfyumaptapt-getbrew(Homebrew)pacman
サブコマンドは以下を用意している。カッコ内はエイリアスだ。
install(i・in)remove(r・rm・un・uninstall)update(upd)upgrade(up・upg)search(find)list installed(ls installed・l・ls・list-installed・ls-installed)list available(ls available・L・la・list-available・ls-available・list --upgradable・ls --upgradable・list upgradable・ls upgradable・list-upgradable・ls-upgradable)info(show)
実際に使ってみせよう。
インストール方法と使い方
pmw は単一のシェルスクリプトで実装している。上の GitHub リポジトリから pmw ファイルをダウンロードし、PATH の通っているところに置けば良い。
内部的には type コマンドを使ってパッケージ管理ツールの存在をチェックし、見つけたコマンドに対応するサブコマンドを拾っている。よって、環境に応じて次のような要領で使用できる。
- CentOS (
yumが使える環境)
$ pmw install vim
# -> yum install vim
$ pmw up vim
# -> yum update vim
- Ubuntu (
aptが使える環境)
$ pmw in -y vim
# -> apt install -y vim
$ pmw ls
# -> apt list installed
- MacOS (
brewが使える環境)
$ pmw in vim
# -> brew install vim
- Windows の Git SDK (
pacmanが使える環境)
$ pmw in vim
# -> pacman -S vim
…とこんな感じ。自分はほとんど install と update・upgrade くらいしか使わないので、コレだけちゃんと動けばいいかなー、というノリで作った。
以下製作に際しての細々
パッケージ管理ツールのコマンド対応表は以下などを参考にした。
最初、install や remove などの単位でサブコマンドを解釈して実行できるようにしようかと考えて、以下あたりを見た。
yum は list available と書けて、apt は同等のことが list --upgradable で…みたいな、コマンドの種類と対応付けを、連想配列みたいに持ちたいなーと思っていた。JSON で書くなら以下のようなイメージ。
{
"yum": {
"install": "install",
"list-available": "list available"
},
"apt-get": {
"install": "install",
"list-available": "list --upgradable"
}
}
JSON ファイルを外に持ったり、jq を使ったりするのは何となく嫌だったので、Bash で連想配列が書けないか調べた。書けなくはないが、declare -A が Bash 4.3 以降でしか使えず、環境を選ぶので却下。
- Bashで連想配列を使用する - Qiita
- bash で配列、連想配列をシェル関数の引数として渡す - Qiita
- bashで連想配列(assoc array / hash ) を使う。 - それマグで!
じゃあもっと単純に、配列で Find するかー、と思い、Bash の配列 (Array) も避けて、カンマ区切りの文字列を cut でちぎって参照することにした。
全体的な実装は、function に切り出して、結果を echo する、不正な値は空文字を echo し、呼び出し元でそれを判断して exit 1 する、という感じ。結果的に事足りたが、なんかシェルスクリプトらしくないというか…。
あと、まだまだ使われる apt-get は、list-installed に dpkg-l、list-available に apt-cache dumpavail を使うなど、apt-get 以外のコマンドも登場することがあり、今回の作りでは対応しきれなかったので諦めた。なんか全体的に判定ロジックを考え直した方が良いんだろうなぁ…。
連想配列でマスタデータを管理したり、それをサクッと find したりするのは、どうも JavaScript に慣れきってしまって、シェルスクリプトでやるのがツラい。でもまぁいいや、apt-get への対応は不十分でもきっと apt が入ってるだろ。
とゆーワケで以上。