Elixirプログラマーは Elixirが好きなあまり、ついついなんでもかんでもElixirでプログラムを記述しがちです。その点における一つ課題は、Elixirプログラミングをしない人のPCに必ずしもElixirの実行環境があるわけではなくElixirプログラムを実行できない場合があるということです。
「どこでもエリクサー」みたいなものを作ってみんなが気軽にElixirスクリプトを実行できるようになれば、Elixirプログラマーとして気兼ねなくElixirを書けて嬉しいですし、Elixirプログラミングをしない人にとってもElixirという素敵な世俗派関数型言語 1 に出会う絶好の機会になるともいえます。
Elixirを使ってサーバーの費用を $2 Million/年 節約できたという話が大きく話題になりました。Elixirの素晴らしさをより多くの方々と共有できればなお嬉しいです。
Elixir実行環境の有無を調べる方法
ターミナルでelixir
コマンドを打つのが一番簡単だと思います。
root@d79eb598ea41:/# elixir
bash: elixir: command not found
他にもいろんなやり方あります。
command -v
コマンドの終了値で判定する方法があります。正常終了の時に0
、そうで無い場合に1
以上の値が終了値となります。
$ command -v bash
/bin/bash
$ echo $?
0
$ command -v nanjakore
$ echo $?
1
上述の特性を利用してこんな感じで条件分岐することができそうです。
if command -v elixir &>/dev/null; then
echo "elixir is installed"
else
echo "where is elixir?"
fi
command -v
コマンドは現在のシェル環境が与えられたコマンドをどのように解釈するかを標準出力に出します。ここではそれは不要なのではブラックホール(/dev/null
)に放り込んでいます。
Elixirが無い所でElixirスクリプトを実行する方法
Elixirが無い所でElixirスクリプトを実行する方法としては、Dockerが手っ取り早いような気がします。
@torifukukaiou さんの「Qiita CLI で取得した.md ファイルのファイル名を Elixir で変更する」に登場する技が活用できそうです。
docker run \
--rm \
--mount type=bind,src="$(pwd)",dst=/app \
--workdir /app \
elixir:1.15.4-otp-25-slim \
elixir -e 'File.write("genki.txt", "元氣があればなんでもできる!\n")'
ポイントは、Elixirのイメージを使うことによりコンテナ内でElixirが実行できるようになることと、バインドマウントすることによりコンテナ内でのファイルの変更がホストマシンに反映されることです。
$ cat ./genki.txt
元氣があればなんでもできる!
ファイルにするほどでもない短いElixirコードは-e
オプションで気軽に実行できます。
以上の技を組み合わせ、本題に取り組みます。
Elixirが無い所でElixirスクリプトを実行するシェルスクリプトを書く
まず、テスト用ディレクトリを作ってその中に入ります。
mkdir -p hoge && cd hoge
テスト用の楽しいElixirスクリプトファイル(my-power.exs
)を作ります。
progress_barパッケージをインストールしてプログレスバーを表示させるだけですが色々楽しめるElixirプログラムです。
cat <<-'EOF' > ./my-power.exs
Mix.install([{:progress_bar, "~> 3.0"}])
[99..44, 44..77, 77..0]
|> Enum.concat()
|> Enum.each(fn i ->
ProgressBar.render(i, 100,
bar: " ",
bar_color: [IO.ANSI.yellow_background()],
blank_color: [IO.ANSI.red_background()]
)
Process.sleep(22)
end)
IO.puts([])
:ko
EOF
Elixirを実行する環境であれば、この時点でelixir
コマンドを用いてElixirスクリプトを直接実行できる所ですが、そうでない場合は実行できません。
$ elixir ./my-power.exs
bash: elixir: command not found
elixir
コマンドが無い時に代わりに使える./dokodemo-elixir.sh
を実装します。
cat <<-'EOF' > ./dokodemo-elixir.sh
#!/bin/bash
docker run \
--rm \
--mount type=bind,src="$(pwd)",dst=/app \
--workdir /app \
elixir:1.15.4-otp-25-slim \
elixir "$@"
echo "完了"
EOF
./dokodemo-elixir.sh
を実行できるようにファイルのアクセス権を変えます。
chmod +x ./dokodemo-elixir.sh
./dokodemo-elixir.sh
で./my-power.exs
スクリプトを実行。
$ ./dokodemo-elixir.sh ./my-power.exs
一回一回コンテナを起動して依存関係をインストールしているのでサクサクとは行かないですが、これでDockerさえインストールされていれば誰でもElixirスクリプトを実行することができるようになりました。
比較的シンプルなElixirスクリプトを共有する場合にこのテクニックが使える場面があるかもしれません。
場合によってはElixir実行環境の有無により分岐をさせても良いかもしれません。
-
Elixir実行環境のある場合
-
elixir
コマンドで Elixirスクリプトを実行
-
-
Elixir実行環境のない場合
-
docker run
でelixir
コンテナを起動してその中で Elixirスクリプトを実行
-
cat <<-'EOF' > ./dokodemo-elixir.sh
#!/bin/bash
if command -v elixir &>/dev/null; then
echo "elixirコマンドが見つかりました。それを使います。"
elixir "$@"
else
echo "elixirコマンドが見つかりませんでした。Dockerを使います。"
docker run \
--rm \
--mount type=bind,src="$(pwd)",dst=/app \
--workdir /app \
elixir:1.15.4-otp-25-slim \
elixir "$@"
fi
echo "完了"
EOF
Livebook
いま流行りのLivebookを使ってElixirコードをノートブックとして共有する方法もあります。この方法だとDockerさえも不要になります。