Windowsでescriptするときにちょっぴり幸せになれる Tips
1.escript ってなに?
ご存じ赤丸急上昇中の Elixirと言えば、WEBフレームワークの Phoenix、インタラクティブUIの LiveView、そして異色のIOTシステム Nervesと、比較的規模の大きなガチな面々が有名で、ライトな用途には向かないよーな印象がある……少なくとも私にはそう見えていた
ところがどっこい、Elixirでもライトな CLI(Command Line Interface)アプリを作ることが出来るのだ。後ほど詳しく触れるが、Elixirプロジェクトのディレクトリで、
mix escript.build
とすれば、CLIアプリのコマンドが作成できる(以下escriptと呼ぶ)。もちろん、shellで起動すればちゃんと動く。
そう、ここまでは良かった。だが、この escriptは Windowsのコマンドプロンプトでは実行できないのだ。残念、Windowsファンは指を咥えて我慢するしかないのか?。
2.escriptを実行するカラクリ
できないとなると、俄然何とかならないものかと悪あがきをしたくなるのが、天邪鬼な技術屋の性分である。
取り敢えず、escriptを実行するカラクリを調べてみよう。えいやっと、escript - helloとする - のバイナリ・ダンプを取ってみると、下図のようになっていた。なるほど、un*xシェルの shebang "#! /usr/bin/env escript"を応用している訳ね[*1]。となれば脈はある
[*1]shebang: un*xシェルは、<ファイル>の先頭に "#! cmd"のパターンを見つけると、代わりに "cmd <ファイル>"を実行する。上の helloでは、実際には "/usr/bin/env escript hello"が実行される。
3."mix escript.build"にバッチファイルを作らせる
では始めよう。
最初に、いつもの通りElixirプロジェクトを用意しよう。
プロジェクト名は "hello"、実行するとコンソールに"Hello world!"と表示する escriptを作る。
C:\home\Elixir>mix new hello
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/hello.ex
* creating test
* creating test/test_helper.exs
* creating test/hello_test.exs
Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:
cd hello
mix test
Run "mix help" for more commands.
escriptのプロジェクトでは、コマンドのエントリーポイントとなる "main(args \ [])"関数を用意する必要がある(下記)。
defmodule Hello do
@moduledoc """
Documentation for `Hello`.
"""
@doc """
Hello world.
"""
def main(args \\ []) do
IO.puts "Hello world!"
end
end
そして、mix.exsの project()に 属性escriptを追加し、コマンド・エントリーポイントのモジュール"Hello"を指定する。
def project do
[
app: :hello,
version: "0.1.0",
elixir: "~> 1.10",
start_permanent: Mix.env() == :prod,
deps: deps(),
escript: escript()
]
end
defp escript do
app_name = "hello"
[
main_module: Hello,
]
end
ここまでが、普通の escriptを作成するための設定だ。
ここからひと捻りして、Windowsのバッチファイルが作られるように改造しよう。
属性escriptには、main_moduleの他に shebangの文字列(:shebang)や escriptファイル名(:path)を指定できるサブ属性がある。これらを利用するのだ。
サブ属性pathは、作成されるescriptファイル名が "hello.bat"となるように設定する。
一方、サブ属性shebangには下記の文字列を設定する。これが手品の種だ。
"%~f0"の部分はバッチファイルのコマンド引数表記で、自分自身のバッチファイル名の絶対PATHに置き換わる表記だ。したがって本例では、Windowsのコマンドプロンプトによって「#! escript "C:\home\Elixir\hello\hello.bat"」と解釈され、そして実行されるのだ。その通り、コマンド "#!" に引数 "escript"と "C:\home\Elixir\hello\hello.bat"を与えて実行せよだ
shebang: "#! escript \"%~f0\"\n"
そして、もう一つの手品の種がこれ。中身が下記で名前が "#!"のバッチファイルを作成し、PATHが通ったディレクトリに置いておく。
@echo off
%*
結果、mix escript.buildで作成された hello.batを実行すると、下記の様にバッチファイルの連鎖が起こり、無事escriptが実行されるのだ。めでたしめでたし。
hello.bat
=> #! escript "C:\home\Elixir\hello\hello.bat"
=> escript "C:\home\Elixir\hello\hello.bat"
mix.exsの修正箇所をまとめると下記の通り。
defp escript do
app_name = "hello"
[
main_module: Hello,
shebang: "#! escript \"%~f0\"\n",
path: "#{app_name}.bat"
]
end
では、試しにやってみる。
ほぼ期待通りだ。途中で echo出力(下から2行目)が出てしまうのはご愛嬌かな
C:\home\Elixir\hello>mix escript.build
Compiling 1 file (.ex)
warning: variable "args" is unused (if the variable is not meant to be used, prefix it with an underscore)
lib/hello.ex:15: Hello.main/1
Generated hello app
Generated escript hello.bat with MIX_ENV=dev
C:\home\shozo\Elixir\hello>hello.bat
C:\home\shozo\Elixir\hello>#! escript "C:\home\shozo\Elixir\hello\hello.bat"
Hello world!
4.エピローグ
「あきらめない、あきらめない、あきらめない ‥‥」
Windowsでも気楽に escriptを書いてみようかなという気持ちが湧いてきた。
ちょっぴり幸せになったかも
Author And Source
この問題について(Windowsでescriptするときにちょっぴり幸せになれる Tips), 我々は、より多くの情報をここで見つけました https://qiita.com/ShozF/items/14a8df28fedde9043750著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .