スクリプト系言語でのシバンなしでの実行方法

GNOME Terminal

概要

以前,「シバンなしファイルでのスクリプト系言語のインタープリターの実行 – senooken.jp」を投稿した。

こちらの内容では,以下2点の欠点があった。

欠点
  1. POSIX準拠シェルが存在しないと実行不可能 (標準Windowsでは実行不可能)。
  2. インタープリターでファイルを指定して実行する場合に構文エラー。

この内,1番目の欠点に関して,「CMDからPowerShellを実行する4の方法 – senooken.jp」や「sh/cmd.exe両対応スクリプトの作成方法 – senooken.jp」の内容により,克服できそうに感じたので,改良したので報告する。

結論としては,以下のコードでUNIX系OSだけでなくWindowsでもシバンなしでもスクリプト系言語を実行できる。

:; command -p tail -n +3 "$0" | exec node  ${1+"$@"}; exit $?
(@powershell -ExecutionPolicy Unrestricted Get-Content "%~f0" ^| Select-Object -Skip 2 | @node %* -) & exit /b
console.log(0);

内容を説明する。なお,今回はインタープリター言語にnode.js (node) を例に説明する。

サンプルファイルを「example/interpreter.cmd at master · senooken/example」にも格納している。

方法

まず,前回の方法は以下のコードにより,シバン (shebang, #!) を使わずに実装していた。

command -p tail -n +2 "$0" | exec php ${1+"$@"}; exit $?
<?php
echo "php";

しかし,この方法はUNIX系OSのshを前提としてコードとなっており,Windowsでは当然ながら動作しなかった

基本ロジックである,「ファイル内の2行目以降をインタープリターに渡して実行」を据え置いて,sh/cmd.exeの両対応により実現する。

まず,Windowsでの2行目以降をインタープリターに渡しての実行は,「CMDからPowerShellを実行する4の方法 – senooken.jp」に記載した「4. 単独ファイル」内容で,以下のとおりに実装できる。

(@powershell -ExecutionPolicy Unrestricted Get-Content "%~f0" ^| Select-Object -Skip 1 | @node %* -) & exit /b
console.log(0)

これに,「sh/cmd.exe両対応スクリプトの作成方法 – senooken.jp」で記載したsh/cmd.exe両対応のテクニックを組み合わせる。

具体的には,shからの実行部分は先頭に:; を指定し,その次の行にcmd.exeでの処理を追加する。行数が増えるため,3行目からファイルの内容を引き渡すように調整する。

:; command -p tail -n +3 "$0" | exec node  ${1+"$@"}; exit $?
(@powershell -ExecutionPolicy Unrestricted Get-Content "%~f0" ^| Select-Object -Skip 2 | @node %* -) & exit /b
console.log(0);

これにより,WindowsとUNIX系OSのどちらからも実行可能なスクリプトファイルを用意できる。

ただし,相変わらず先頭にプログラミング言語とは無関係な内容が追加されているので,代償としてインタープリター (例: node) で直接実行できないという以下の欠点は残る。

欠点
  1. インタープリターでファイルを指定して実行する場合に構文エラー。

しかし,例えば,拡張子を付けずに,ユーザーに単なる実行ファイルとして提供するような場合には有効な方法だと思う。

結論

スクリプト言語でシバンを指定せずにプログラムを実行するテクニックの改良版の続報を記した。

他で発見した方法により,以前の課題が解決できた。ニッチな内容で役立つ場面は限られるだろうが,珍しいノウハウだと思う。

タイミングを見て役立てたいと思う。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です