はじめに
UNIXコマンドって多すぎて覚えられないですよね!そこで、ランダムでコマンドを教えてくれるコマンドcmdsayを作りました!
このコマンドは/usr/bin
配下のコマンドとその説明をランダムで表示します!
.bashrc
や.zshrc
にこのコマンドを書いてシェルログインのたびに実行するようにしておけば、あなたの知らないコマンドに巡り会えるかも!
この記事ではコマンドを作成し、Homebrewパッケージとして公開するまでの手順を記載しています。
(このコマンド、当初はシェル設定ファイルに直接シェルスクリプト書いており、パッケージとして公開するつもりはなかったのですが、アドベントカレンダーネタとしてつまらないかもと思い、Homebrewパッケージとして公開に至りました。)
コマンドの作成
シェルスクリプトでコマンドの作成を行います。
コマンドの流れは非常にシンプルです。
-
/usr/bin
配下のコマンドをランダムで1つ選択 -
whatis
でコマンドの説明を取得 - 2.を
cowsay
に渡し、シェルに出力
この自作コマンドの中でメインとなっているコマンドはwhatis
とcowsay
です。
whatis
はコマンド検索を行うコマンドで、whatis コマンド名
で該当コマンドと簡易的な説明が表示されます。
cowsay
はcowsay 文字列
で、与えた文字列をキャラクターに喋らせます。
sort
は引数として-R
を与えるとランダムソートを行います。
#!/bin/sh
while : ; do
# ランダムでコマンドを取得
COMMAND="$(basename $(find /usr/bin -type f | sort -R | head -n 1))"
# whatisでコマンドの説明を取得
DESCRIPTIONS="$(whatis $COMMAND)"
# 取得したコマンドに説明があるとき
if (echo $DESCRIPTIONS | grep -v "nothing appropriate" > /dev/null); then
DESCRIPTION=$(echo $DESCRIPTIONS | grep "^$COMMAND" | sort -R | head -n 1)
if [ -n "$DESCRIPTION" ]; then
break
fi
fi
done
# cowsayのキャラクターをランダムで選択する
COW=$(basename $(ls -1 /usr/local/Cellar/cowsay/*/share/cows/*.cow | sort -R | head -n 1 | sed 's/\.cow$//'))
# 見やすいようにコマンドと説明の間に改行を入れて、最終的な出力をする
echo $DESCRIPTION | sed 's/ - /\'$'\n/' | cowsay -f $COW -n
unset COMMAND
unset DESCRIPTIONS
unset DESCRIPTION
unset COW
工夫した点
すべてのコマンドにwhatis
による説明があるとは限りません。そのため、ランダムにコマンドを選択する処理を無限ループで包み、if (echo $DESCRIPTIONS | grep -v "nothing appropriate" > /dev/null);
で説明があるコマンドのみを選択するようにしています。
また、whatis
はコマンド名 - 説明
というフォーマットで結果を返すのですが、引数として1つのコマンドを与えても、複数の結果が返ってくることがあります。これは与えたコマンドに関係するコマンドも返すためです。
例えば、whatis python
を実行するとpython
の他に関係するコマンドのpydoc
やpythonw
も返ってきます。
$ whatis python
pydoc(1) - the Python documentation tool
python(1) - an interpreted, interactive, object-oriented programming language
pythonw(1) - run python script allowing GUI
今回は1つのコマンドの説明を返したいため、この中からから更にランダムで1つ選択するような処理もしています。
cowsay
は-f
オプションでキャラクターを指定できます。今回はキャラクターもランダムで表示するようにしています。
自作コマンドをHomebrewパッケージの公開
macのパッケージマネージャHomebrewでは、brew tap
を使うことで、公式以外のformulaを追加でき、これによって自作のコマンドやアプリを簡単に公開することが可能です。
formulaとは、ビルド方法を記載したrubyファイルのことです。
パッケージ公開の手順としてはざっくり以下のように行います。
- 公開するコマンドを作成
- formulaファイルを作成
- githubにHomebrew配布用のリポジトリを作成
- 自作コマンドとformulaファイルをアップロード
配布用リポジトリの作成
Homebrew配布用のリポジトリをgithubに作成します。
このとき注意する点として、リポジトリ名をhomwbrew-
から始める必要があります。
また、本来はhomebrew-
から始まるリポジトリを一つ用意すればよいのですが、今回は2つのリポジトリhomebrew-tap
とcmdsay
を作成しています。homebrew-tap
でformulaを管理し、cmdsay
で自作コマンドのソースコードを管理するためです。
自作コマンドのソースコードをアップロードしたリポジトリで、リリースノートを作り、インストールリンクを作成した後、formulaファイルにインストールリンクを記載します。
自作コマンドをアップロード
自作したコマンドをgithubにアップロードします。今回はcmdsay.sh
をリポジトリcmdsay
にpushします。また、後々自作したコマンドをアップデートをすることを想定し、タグを付けます。
$ git add cmdsay.sh
$ git commit -m 'initial commit'
$ git tag v0.0.1
$ git push origin v0.0.1
Releaseノートの作成
タグをpushしたら、リリースノートを作成します。リポジトリを開いてreleaseタグをクリックし、Releaseページに移動したら、Draft a new releaseをクリックします。
追加したタグを選択し、タイトルを入力します。そしたらページ下部のPublish releaseをクリックし、Releaseノートが出来ます。ソースコードのリンク先**Source code (tar.gz)**は次のformulaの作成で使用するためコピーしておきます。
formulaの作成
brew
コマンドにはformulaの雛形を生成するコマンドが存在します。引数にはダウンロードリンクを与えます。先程コピーしたものを与えてください。
$ brew create [ソースコードのリンク先]
するとエディタでformulaが開かれ、編集画面に移ります。
最低限必要なのはurl
,sha256
とinstall
メソッドです。
url
とsha256
1は設定済みなので、install
メソッドを編集していきます。
install
メソッドでビルド手順を記載します。
bin.install
にはビルドの結果得られた実行ファイルを指定します。そうすることで、/usr/local/bin
配下にシンボリックリンクを作成できます。
また、他のformulaと依存関係がある場合はdepends_on
を指定する必要があります。
今回はcowsay
とシェルスクリプトをコンパイルするshc(shell script compiler)
を指定します。
最終的なformulaは以下のようになります。
class Cmdsay < Formula
desc "random show cmd description"
homepage ""
url "https://github.com/Kyou13/cmdsay/archive/v0.0.1.tar.gz"
sha256 "[生成されたsha256ハッシュ]"
depends_on "cowsay"
depends_on "shc"
def install
system "shc", "-f", "cmdsay.sh", "-o", "cmdsay"
bin.install "cmdsay"
end
end
このformulaをhomebrew-tap/cmdsay.rb
として保存したら、githubのformula管理用リポジトリにアップロードします。
自作コマンドをbrewでインストールし確認する
実際にアップロードした自作コマンドをインストールします。
$ brew tap [githubユーザ名]/tap
$ brew install [githubユーザ名]/tap/[自作コマンド名]
私の場合は以下のようになります。
$ brew tap Kyou13/tap
$ brew install Kyou13/tap/cmdsay
コマンドが実行できるかを確認したら、完了です!
おわりに
自作パッケージの公開は敷居が高そうと思っていました。しかし、今回始めてHomebrewパッケージを公開してみて、とても簡単な手順で公開することが出来ました!
-
sha256
が設定済みではない場合やファイルの更新を行った場合はopenssl dgst-sha256 [filename]
を実行して取得する ↩