シバンなしファイルでのスクリプト系言語のインタープリターの実行
背景
PHPを勉強しており,PHPの実行方法を調べていた。その中で,シェルスクリプトで実行する方法が目に映った。
いわゆるシバン (shebang, #!
) を使った実行方法だ。この方法はその他のスクリプト系言語のインタープリターの指定にも使われており,よく見かけるものだ。ただ,この方法は絶対パスでインタープリターを決め打ちで指定するという点で前からいまいちだと感じていた。
また,インタープリターへの絶対パスを使わない場合は,「Perl, Python 及び Ruby スクリプトにおける正しいshebangの書き方 – Qiita」で説明されている通り,言語独自のオプションや仕様をうまく使って,共通のシバン (#!/bin/sh
) を使いうまく方法がある。これはこれで言語ごとに,書き方が異なるし,PHPの場合の事例が記されていない。
絶対パスを使わずに,統一記法で,ファイル名での実行時にスクリプト系言語のインタープリターを起動する方法がないかを考えていた。完璧ではないものの,実現方法が見つかったので記録としてここに記す。
方法
その方法は以下のように1行目を記入することだ。
command -p tail -n +2 "$0" | exec php ${1+"$@"}; exit $?
<?php
echo "php";
内容は以下の3の手順で構成されている。
簡単にいうと,ファイル内の2行目以降をインタープリターに引き渡すことで,1行目の標準シェルからのインタープリターの呼び出しコードをスキップしている。
これにより,シバンを使わずにインタープリターを実行できる。この方法の利点は以下の4点だ。
逆に欠点は以下の2点だ。
特に,欠点の2番目の影響が大きい。1行目はインタープリターの言語と全く無関係の構文のため,インタープリターの引数にファイルを指定して実行すると,確実に1行目でエラーが出る。
これを防ぐには,インタープリターにファイルを指定する際にも,tail -n +2
相当の処理をして,常に2行目からファイルの内容を標準入力経由で渡す必要がある。
この欠点のため,この方法はUNIX系OSで常にファイル名での実行のみを想定する場合には有効だ。しかし,主にWindowsのように非UNIX系OSでファイル名でそもそも実行できない,またはインタープリターにファイルを指定して実行したい場合には向いていない。
結論
私見としては,インタープリターが必要なスクリプト系言語での開発では,シバンを付けないほうがよい。シバンという絶対パスを指定する限り,移植性の低下は避けられない。
ファイル名で実行したい場合,パッケージングによりバイナリー形式にして配布したほうがよいだろう。
なお,今回の方法を流用して,「PowerShellを単一.cmdファイルから実行する方法」も掲載した。
“シバンなしファイルでのスクリプト系言語のインタープリターの実行” に対して1件のコメントがあります。