この記事に触発されて、Elixir の練習として似たようなコマンドを作った。
Unixコマンド”yes”についてのちょっとした話 | コンピュータサイエンス | POSTD
この世の全てを否定するコマンドno
記事内ではyes
コマンドが扱われていたがそのまま作ってもしょうもないので、no
コマンドを作ることにした。
仕様はほぼyes
と同じ。標準出力に永久にn
を出力し続ける。
こんな感じで使えるようにする。
> no n n n n n n n ...
または、
> no | sh work_a_lot.sh
annoying boss に
「安月給でもっと働け!!プロ意識をもて!!やりがいで駆動しろ!!」と言われましたか?
そういう時にこのコマンドが役に立つはずです。
※ 効果には個人差があります
さっそく作る
環境
> elixir -v Erlang/OTP 20 [erts-9.1.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] Elixir 1.5.2
プロジェクト作成
> mix new no > cd no
mix.exs
修正
Elixir で実行可能ファイルを作成するには、escript
を使えとのこと
line:9
escript を使用するためにモジュールを指定line:22-24
モジュール名などを返す関数を書くのが良さげ
ここで指定した module の No.main/1
がエントリポイントになる
実装
普通にループするだけじゃあしょうもないので、プロセスをたくさん生成してそれぞれがn
を出力し続けられるようなオプション-p
を追加した。
あと、その並列実行の様を観測できるように-d
でPIDを見られるようにもした。
OptionParser めっちゃ便利。
こうやったほうがCOOLだよ!などがあれば教えてもらえるととても嬉しいです。
ビルド
実装が済んだらビルド
mix.exs
があるディレクトリで実行する
> mix escript.build
カレントディレクトリに実行可能ファイルが生成されるはず
実行
カレントディレクトリに
> ./no -p 100 n n n n n ...
とりあえず動いている
デバッグオプション有り
> ./no -p 100 -d {"n from process no.47", #PID<0.122.0>} {"n from process no.47", #PID<0.122.0>} {"n from process no.47", #PID<0.122.0>} {"n from process no.40", #PID<0.115.0>} {"n from process no.47", #PID<0.122.0>} ...
やったぜ
速度的にどうなの
速度が気になったので計測してみた
> ./no | pv -r > /dev/null [93.7KiB/s]
yes
コマンドはというと、
> yes | pv -r > /dev/null [31.6MiB/s]
no
コマンド、桁違いに遅くて笑っちゃう!!!
まあまあ落ち着け、並行処理で逆転だぜ!
> ./no -p 100 | pv -r > /dev/null [1.12KiB/s]
より遅くなるってどういうことなの...
まとめ
- 言語の練習題材としてLinuxコマンドを再実装するのは良い
- 機能のサイズ的に手頃なのが多い
|>
で処理繋いでいくのは気持ち良い- なんで遅くなるのかわからん
- 気が向いたら調べる
- Hex への登録
気が向いたら続く。
(参考)
- https://github.com/rizafahmi/elixirdose-cli
- Overview of Elixir executables
- Elixir 基礎文法最速マスター - Qiita
- Elixirでコマンドラインツールを作る - Qiita

- 作者: DaveThomas
- 出版社/メーカー: オーム社
- 発売日: 2017/07/14
- メディア: Kindle版
- この商品を含むブログを見る