このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
shebang の行かどうかは、
先頭が#! で開始しているかどうかを調べればいい。
if "%SHEBANG:~0,2%" == "#!" echo SHEBANG!
ただ、一昨日のプログラムでは、
for によって特殊変数に行を読み込んでいたため、
そのままでは文字列の部分比較ができない。
そのため、一度普通の変数に格納する必要がある。
set SHEBANG=%s
#! を取り除いたものが、処理系のコマンドだ。
/usr/local/bin/perl -w とかが入る。
先頭から 0 ベースで 2 番目以降の文字を抜き出せば OK。
set HANDLER=%SHEBANG:~2%
さて、最後に Windows ならではの処理をしておこう。
Windows にはドライブの概念がある。
ハンドラがパスを含めずに書いてあれば、
Windows も PATH を探すので問題ないが、
ドライブを含まない絶対パスの場合に困る。
Shebang を含むファイルは大抵そうだ。
なので、絶対パスであり、かつドライブが含まれない場合、
スクリプトのドライブとみなすことにしよう。
バッチファイルの引数でスクリプトのファイルが渡るので、
%1 という特殊変数で引数のファイル名を得ることができる。
それに対して、ドライブのみ展開する記法を使えばいい。
if "%HANDLER:~0,1%"=="/" set HANDLER=%~d1%HANDLER%
後は引数をつけて実行するだけだ。
%HANDLER% %*
よし、バッチファイルにしてみよう。
========== shebang.cmd ==========
@echo off
for /f "usebackq delims= eol=" %%s in ("%~1") do (
rem # 行を変数 SHEBANG に格納する。
set SHEBANG=%%s
rem # 一行目だけでいいので繰り返さずに抜ける。
goto break;
)
:break
rem #! で始まるかどうか調べる。
if not "%SHEBANG:~0,2%"=="#!" (
rem # ファイルが見つからない、または
rem # shebang が見つからない場合、シェルにお任せ。
rem # %* は渡されたコマンドライン全体だ。
%*
rem # :eof はファイルの最後を意味する特殊なラベル。
goto :eof
)
rem # ハンドラ(処理系)のパスや引数を切り出す。
set HANDLER=%SHEBANG:~2%
rem # 絶対パスであり、かつドライブが含まれない場合、
rem # スクリプトのドライブとみなす。
if "%HANDLER:~0,1%"=="/" set HANDLER=%~d1%HANDLER%
rem # ハンドラに引数を渡して実行。
%HANDLER% %*
========== end of shebang.cmd ==========
よし、できた。テストのためのファイルを作ろう。
良くある perl スクリプト。
========== test.cgi ==========
#!/usr/local/bin/perl
print "Hello World!\n"
========== end of test.cgi ==========
へぼっ。仕方ないか。
C:\usr\local\bin\perl.exe は用意しておくこと。
Windows では ActivePerl かな。
んでもって、Windows っぽいのを。
netsh 使って、dns の設定を表示する。
netsh も、# がコメントなので使える。
netsh は、-f オプションを使ってスクリプトを実行する。
========== test.nsh ==========
#!netsh -f
interface ip show dns
========== end of test.cgi ==========
実行してみる。
c:\>shebang test.cgi
Hello World!
c:\>shebang test.nsh
Configuration for interface "Wireless Network Connection"
DNS servers configured through DHCP: 192.168.0.1
Register with which suffix: None
Configuration for interface "Local Area Connection"
DNS servers configured through DHCP: 192.168.0.1
Register with which suffix: None
いい感じ。
shebang.cmd を !.cmd などに変えて、
パスの通った場所に置いておけば、
! test.nsh
の様に実行できる。だからどうしたって感じだが。