3-2.A Magic Header for Starting Perl Scripts 日本語訳 の変更点

Top > 3-2.A Magic Header for Starting Perl Scripts 日本語訳

A Magic Header for Starting Perl Scripts 日本語訳

原文リンク:http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/TPJ/2003/0304/0304c/0304c.htm

The Perl Journal 2003年4月
Péter Szabóによる

Péterはハンガリーのブダペスト技術経済大学でコンピュータ科学と情報科学を研究しています。 彼の主な関心はプログラミング言語、モデル検証、およびコンピュータ組版です。 彼と[email protected]でコンタクトすることができます。
----
ほとんどのPerlスクリプトは、#!とワード'''perl'''(例えば、#!/usr/local/bin/perl -w)を含む行で始まります。 この行は、Unixオペレーティングシステムに、現在のファイルをバイナリ実行可能ファイルとして扱うのではなく、記述された'''perl'''インタプリタを記述されたオプションと共に起動し、そのインタプリタがそのPerlスクリプトを取り扱うように指示しています。 この最初のー行の概念は単純ですが、それを普遍的に適用できるように書くのはとても困難になりがちです。

たとえば、'''#! /usr/local/bin/perl -w'''を記述することは、'''perl'''が'''/usr/bin'''にある多くの、おまかせ設定済みLinuxマシン上では、'''my_script.pl: No such file or directory'''という紛らわしいメッセージの原因となります。'''#! /usr/bin/perl -w'''と記述することそんなLinuxマシン上の問題を解決はしますが、'''perl'''が標準の置き場所が'''/usr/local/bin'''である多くのSolarisシステムとの互換性を破壊します。#!の後で記述するべき標準的な'''perl'''の場所は無いという悪いニュースがあります。さらに悪いことに、いくつかの古いUnixシステムは#!行の記述に非常に厳格なルールを課します。結局、以下から選択することになります。
-ユーザーベースの大多数のために動くパスを記述します。
-非互換性を文書化し、問題がある場合は、丁重に手動でスクリプトを変更するようユーザーにお願いします。
-変更を自動化するインストールスクリプトを書きます。 (どのようにユーザーがインストールスクリプトを開始するのか?'''perl install.pl'''と入力することで、かな。)
-どこでも動作するソリューションを見つけます。 

この記事では最後のオプション-マジックPerlヘッダー、任意のUNIXオペレーティング・システム上でPerlスクリプトを起動するための複数行のソリューションについて説明します。

***一般的なワンラインの落とし穴 [#ke44fd16]

最も露骨な#!ワンライナーも、どうもいまひとつです。
-'''#!/usr/local/bin/perl -w -T'''の記述は、動作しません。なぜなら、いくつかのUNIXオペレーティングシステムでは'''#!'''の後は一つのコマンドラインスイッチのみ許されています。このワンライナーは、Linux上で動作しません。
-'''#!/usr/local/bin/perl -wT'''の記述は、動作しません。なぜなら、いくつかのUNIXオペレーティングシステムでは'''#!'''の後にスペースが求められています。このワンライナーは、/user/local/binが存在する場合のみLinux上で動作します。(ただし、普通はない)
-'''#! /usr/local/bin/perl -wT'''の記述は、動作しません。なぜなら、'''perl'''は恐らく/usr/bin/とか他のどこかに置かれているだろうからです、Debian Linuxのように。(要確認:あなたのスクリプトのユーザーはperlバイナリの場所を見つけることができたり、スクリプトの最初の行を適切に変更するのに十分な教育を受けていないかもしれません。またあるセキュリティの設定上では、たとえ彼らが正確な変更のし方を知っていたとしてもそれをする許可は持っていないかもしれません)このワンライナーは、おまかせ設定Linux上ではまれにしか動きません。
-'''#! perl -wT'''の記述は、動作しません。なぜならいくつかのUNIXシステムは、#!の後は(/からはじまる)絶対パス付の動作可能ファイル名が求められています。このワンライナーはLinux上では動きません。
-'''#! /usr/bin/env perl -wT'''の記述は、動作しません。なぜならいくつかのシステムはコマンド名の後にはゼロかひとつのアーギュメントしか許されません。(もっと言えば、いくつかのシステム上では最初の行の長さには制限があり、それは32文字あるいは64文字以下です。)コマンドライン以外の場所で'''-T'''スイッチを記述するのは非常に難しいでしょう。('''-w'''スイッチの方はより易しいです:Perlコードの前に'''BEGIN{$^W=1}'''と書くだけです。'''-T'''スイッチはセキュリティスイッチであり、その記述が遅いと、悪意のある事故のバックドアを開けることになります。あなた(プログラマー)はここはとりわけ注意しなければなりませんが、正しいスイッチを記述する場所がないので、難しいです。このワンライナーはLinuxでは動きません。
-'''#! /usr/bin/env perl'''の記述は、いずれにしろ動作しません。なぜなら'''env'''はいくつかのシステムでは無かったり別のところに置かれているからです。このワンライナーはLinux上では動きます。

***マジックPerlヘッダーを作る [#re8fd208]

#!の単一行で一般的なケースの問題を解決する方法が無いのは明らかです。なぜならスクリプトを走らせるためにPerlを起動する移植可能な方法がないからです。複数行での解決策が必要になるでしょう。このセクションではこの解決策を作り始めます。この先、私は問題点や制限を特定し、次の章では、最終的な、どんなUnixシステム上でもPerlスクリプトが動作する、完全な、マジックPerlヘッダーを提示します。

スクリプトの、唯一の移植可能なはじめかたは、
 #! /bin/sh
です。
'''/bin/sh'''は全てのUNIXシステム上で使えます。しかし、それはBourneシェルバリアント(Bashとかash)、Kornシェルバリアント(pdkshとかzsh)そしてCシェルバリアント(cshやtcsh)を含む他のシェルへのシンボリックリンクであるかも知れません。多くのUNIXユーティリティと、(ANSI C, POSIX.2, BSD4.3と適合する)libc '''system(3)'''関数は'''/bin/sh'''の動作を当てにしています。だから、'''/bin/sh'''が存在し、Bourneシェル、Kornシェル、またはCシェルの変種であると仮定することは、かなり合理的です。Linuxでは、'''/bin/sh'''は通常'''/bin/bash'''へのシンボリックリンクです。(Linuxのインストールディスクでは、時々'''/bin/ash'''へのシンボリックリンクであったり、BusyBoxの内蔵ashへのシンボリックリンクです)Win32 MinGW MSYSでは、'''/bin/sh'''はBashですが、/bin/bashはありません。Solarisでは、'''/bin/sh'''はSun独自の、単純化したBourneシェルクーロンですし、Digital UNIXも'''/bin/sh'''のなかは簡単なBourneシェルクーロンです。(多くのシェルスクリプト中に見受けられる'''#!/bin/sh --'''行は、実行可能のために任意のファイル名を許容しますが、ここでは動きません。なぜなら、tcshは--スイッチにエラーを出します。)

私たちは、$PATH中で'''perl'''の実行ファイルを検索し、正しいスイッチとともにそれを実行する簡単なシェルラッパーを書くことができます。 実際、これは、.batバッチファイルを使ったWin32システム上で動作する唯一の方法です。 一つの解決策の候補は、
 ## file my_script.sh, version 1
 #! /bin/sh
 perl my_script.pl

 ## file my_script.pl
 # real Perl code begins here
です。
これは、以下のような問題があります。

1.これは、コマンドライン引数を渡すことはありません。

2.それは、 '''exit()'''ステータスを伝達しません。

3.これは'''$PATH'''のなかのPerlスクリプトを見つけることができません。カレントディレクトリからPerlスクリプトを取ってくるだろうし、それは通常間違いです。また、セキュリティ上の問題を提示する可能性があります。

4.これは、2つの別々のファイルを必要とします。

問題1-3は非常に簡単に克服することができます。

 ## file my_script.sh, version 2
 #! /bin/sh
 exec perl -S -- my_script.pl "$@"

すべてのBourneシェルとKornシェル(例えば、Gnu Bash、ash, zsh, pdksh, Solarisの'''/bin/sh'''など)は'''my_script.sh'''を正しく解釈することができます。 しかしながら、Cシェルは「変更されていない、シェルに渡されるすべての引数"のための異なる書き方を使っています。'''"@"'''の代わりに'''$argv:q'''を使うのです。'''perlrun(1)'''のマニュアルページには、Cシェルを検出する印象的な構築物が記述されてます。
 eval '(exit $?0)' && eval 'echo "Korn and Bourne"'
 echo All
'''"All"'''というメッセージは、全ての3つのシェルタイプで出力されますが、KornシェルとBourneシェルの場合のみ'''"Korn and Bourne"'''メッセージを出力します。(zshでは、結果は'''$?'''の値に依ります。しかしこれは問題を起こしません。zshは我々の使うcshとBourneシェルの構造を両方理解するからです。)ここでのトリックは、'''$?'''は前コマンドの終了ステータスで、初期値0ですが、Cシェルでの'''$?0'''は変数'''$0'''が存在するために"1"を返すテストであるということです。

Cシェル検出コードの'''echo'''を'''exec perl'''に変えることができて、それで終わりです。

 ## file my_script.sh, version 3
 #! /bin/sh
 eval '(exit $?0)' && exec perl -S — "$0" "$@"
 exec perl -S -- "$0" $argv:q

今、私たちは最初の魔法のステップを作る準備ができています。'''my_script.pl'''とmy_script.sh'''を一つのファイルにつなげましょう。そのファイルは、shellから走らせると自らをperlを使って起動します。(ちょっとの間csh互換を忘れましょうーあとで戻ります)

単純な試みは次のようになります。

 #! /bin/sh
 eval 'echo DEBUG; exec perl -S $0 ${1+"$@"}'
 if 0;
 # real Perl code begins here

残念ながら、これは本当のPerlコードを実行しません。数多くのDEBUGメッセージを生み出します。 それはPerlが持つビルトインハックのためです。:最初の行が#!ではじまり、'''perl'''という文字が無い場合、Perlはスクリプトを解析するのではなく、指定されたプログラムを実行します。 詳細については'''perlrun(1)'''マニュアルページの冒頭を参照してください。

'''perlrun(1)'''マニュアルページで提案されている次の簡単なトリックでは、最初の行に'''perl'''という文字がが含まれています。

 #! /bin/sh — # -*- perl -*-
 eval 'exec perl -S $0 ${1+"$@"}'
 if 0;
 # real Perl code begins here

これはLinuxを含む多くのシステム上で動作しません、なぜならOSはコマンドライン('''/bin/sh, --# *-* perl -*-, ./my_script.pl''')を起動し、そしてシェルは完全に偽りのスイッチに関する不快なエラーメッセージを出力します。

そこで最初の行を省略することができて、

 eval 'exec perl -S $0 ${1+"$@"}'
 if 0;
 # real Perl code begins here

このソリューションは、トーマス・エッサーの'''epstopdf'''ユーティリティにインスパイアされています、そしてLinuxシステム上で、'''perl my_script.pl'''と'''./my_script.pl'''の両方で動作しているようです。 しかし、私たちはもっとよくできます。
----
このソリューションは、トーマス・エッサーの'''epstopdf'''ユーティリティにインスパイアされています、そしてLinuxシステム上で、'''perl my_script.pl'''と'''./my_script.pl'''の両方で動作しているようです。 しかし私たちはもっとよくできます。このスクリプトの主な欠陥は、
「オペレーティング・システムはASCII文字で始まる実行可能ファイルをスクリプトであると認識し、'''/bin/sh'''を介してそれらを実行している」ということにたよっているということです。 いくつかのシステムでは、"Cannot execute binary file" とか "Exec format error" が発生する可能性があります。

このスクリプト内の主要な欠陥は、オペレーティング・システムはスクリプトなどのASCII文字で始まる実行可能ファイルを認識し、/ binに/ shを介してそれらを実行しているという事実に依存しているということです。 いくつかのシステムでは、発生する可能性がある」、「バイナリファイル '' Execのフォーマットエラーまたは実行できません " '。
このスクリプトは非常にトリッキーであることに注意してください。 なぜなら、最初の行はPerlとBourne互換シェルの両方に有効だからです。(これは、Cシェルでは動作しませんが、我々は後にその問題を解決します。)

最初の行はPerlとBourne互換シェルの両方に有効であるので、このスクリプトは非常にトリッキーであることに注意してください。 (これは、Cシェルでは動作しませんが、我々は後にその問題を解決します。)

解決策は、別の問題があります:誰かがスクリプトになどにスペースや他の変な文字、との奇妙なファイル名を与えた場合
このソリューションには、別の問題があります:スクリプトになどにスペースや他の変な文字との奇妙なファイル名を与えた場合、たとえば
 -e system(halt) 

その後、コマンド
すると、コマンド
 perl -S -e system(halt) 

ユーザーの$ PATH上の停止という名前の危険なプログラムがある場合には、災害である、実行されます。 さらにオプションの認識からPerlを防ぐために-この問題は、シェルから$ 0引用して、でそれを付けることによって、簡単に解決することができます。
は実行するが、ユーザーの'''$PATH'''上の'''halt'''という名前の危険なプログラムがある場合には、災害となる。この問題は簡単に解決可能で、シェルから'''$0'''を引用してそれに--を付加することで、Perlがその先のオプションを解釈させなくすればよい。

----

!私たちは#ラインのための2つの相反する要求を持っている:ポータビリティの要件は、それが正確に#でなければならないということです! / binに/ shを 。 それは、前述の無限DEBUGループを回避するために、単語のperlが含まれている必要があります。 これらの要件の両方をsatisifyが、何のOSが最初に解析すると、Perlは第二を見つけるので、perlの-xを実行した後、2つの行を持っていることについてすることができます単一の行はありませんか?

 #! /bin/sh
 eval 'exec perl -S -x — "$0" ${1+"$@"}'
 if 0;
 #!perl -w
 # real Perl code begins here

ここでのトリックは、-xスイッチで呼び出されたときにPerlが、#!にperlのすべてを無視するということです。 nonUNIXシステムのユーザは、perlの-xでこのスクリプトを呼び出す必要があります。 UNIXユーザーが自由に./my_script.pl、perlのmy_script.pl、perl の-x my_script.plのいずれかを選択し、さらにSH my_script.plことがあります。

このスクリプトの微妙なバイリンガルのトリックは、勉強の価値があります。 ファイルはperlの-xによって読み取られると、それはすぐに実際のPerlコードにスキップします。 ファイルがシェルによって読み込まれると、それはevalの行を実行します。それは、スクリプトのファイル名とコマンドライン引数でのperl -xを呼び出します 。 物事は、引数にスペースまたは引用符が含まれている場合でも動作するように、二重引用符と$ @は 、シェルスクリプトの妙技です。 -Sオプションは、ほとんどのシェルは(すなわち、$ 0は 、ユーザが入力したコマンドである)変わらない$ 0残すため、再び$ PATHにファイルを検索するためのPerlを伝えます。

2行目と3行目は有効なノーオペレーションPerlコードが含まれていますが、Perlは理由-xスイッチのこれらの行を解釈することはありません。 それはすぐに/ bin / shを起動しますので、これらの株はまた、完全にperlのmy_script.plによって無視されます。 しかし、 やる Perlでこのスクリプトを内蔵して、2行目と3行目は、コンパイルされ、解釈されますユーザー負荷は、無害なノーオペレーションコードが実行され、何の構文エラーが発生していない場合。

残る欠陥がまだあります。
-これは、Cシェルでは動作しません。 我々はすでに、このセクションでは、この以前に解決しています。
-これは、#と比較し、エラーメッセージに行番号を報告します!perlの-wライン。
-ロケール設定が無効である場合には、警告を出力します。 (醜い警告メッセージを表示するには、スクリプトを実行する前に、バッシュで「無効な輸出LANG = 'を設定してみてください。) 

行番号の問題に関しては、Perlを行う内蔵のは、このような構築物でスクリプトを再読み込みするために使用することができます。

 BEGIN{ if(!$second_run){ $second_run=1; do($0); die $@ if $@; exit } }

BEGINは、ファイル全体をコンパイルすると、おそらく間違った行番号と構文エラーに文句からPerlを防ぐために、ここで必要とされます。 ダイの$ @ $ @を命令が正しく実行時 ​​エラーメッセージが出力されます場合 。 $ @をの詳細については、(1)perlvarを参照してください。 残念ながら、コード

 BEGIN{ if(!$second_run){ $second_run=1; do($0); die $@ if $@; exit } }
 die 42;
  
余分なエラーメッセージは「失敗したコンパイルは中止BEGIN。」が得られます ダイ42は、実行時 ​​エラーではなく、コンパイル時エラーが発生するため、このエラーが混乱しています。 メッセージを取り除くために、我々は何とか出口を排除し、}}の後に入力を解析し続けることはないPerlを伝える必要があります。 我々は十分に早く構文解析を停止する__END__トークンを使用します。

ロケールの警告が始まる複数行のメッセージである "perlの:警告:設定のロケールに失敗しました。」 環境変数LANG、LC_ALL、およびLC_ *で指定されたロケール設定が正しくない場合はPerlはこれを放出します。 (1)詳細についてはperllocaleを参照してください。 この警告のための本当の修正がインストールされ、正しくロケールを指定されています。 壊れたロケールがそれらに害を行いませんので、しかし、ほとんどのPerlスクリプトは、とにかくロケールを使用しないでください。

Perlはロケールの問題のための良好な診断ツールではありますが、ほとんどの時間は、我々は特にない、CGIで(これらの警告は、Webサーバのログファイルを埋めるだろう)、このような警告メッセージを望んでいない、またはプログラムがいくつかのシステムデーモンプロセスである場合、通常の操作では標準エラー出力への書き込みが禁止。 システム管理者は、実際にロケール設定を修正する必要がありますが、それは時間がかかることがあります。 ほとんどのユーザーは、とにかく、ロケールに依存しない単一のPerlスクリプトを実行するには数週間待機する時間を持っていません。

perllocale(1)のマニュアルページには、PERL_BADLANGは 、ロケールの警告を取り除くために真の値に設定する必要があることを述べています。 実際に、PERL_BADLANGは空でない、数値以外の文字列(例えば、PERL_BADLANG = 1が機能しない)に設定する必要があります。 だから我々は、シェルスクリプトのセクションで= xをPERL_BADLANGするように設定します。 Perlはシェルの前に呼び出された場合、これは効果がありませんので注意してください。 例えば、perlの 、perlの-x、perl の-S、およびperlの-x -SすべてのシェルがPERL_BADLANGを変えるチャンスを持っている長い前に警告を発します。

***完成したヘッダ [#f24b67bd]

一緒にすべてを組み合わせることで、我々はマジックのPerlヘッダの最終版を持っています。 参照例1 。ファイルは、UNIXシステム上で実行可能な属性を持っている必要があります。

このヘッダーは、複数の言語で有効であるので、その意味は、インタプリタによって異なります。 幸いなことに、すべての通訳のヘッダの最終的な効果は、perlはヘッダの後、実際のPerlコードを実行して呼び出されるということです。 ヘッダがこれを実現する方法を見てみましょう:

-Perlで実行すると、-xスイッチを使用せずに、Perlは/ binに/すぐにshを実行します。 (/ binに/ shがシェルのいずれのタイプであってもよいです。)
-BourneシェルとKornシェルの変異体は、ファイルとして解釈します: 

 #! /bin/sh —
 true && eval '...; exec perl -T -x -S "$0" #{1+"$@"}' # comment
 garbage

    そこで、彼らはperlの-xを実行します。 

-Cシェルの変異体は、ファイルとして解釈します: 

 #! /bin/sh --
 false && eval '...' ;
 eval '...; exec perl -T -x -S — "$0" $argv:q'  # comment
 garbage
そこで、彼らはperlの-xを実行します。 

-ヘッダーの2行目の最後のバックスラッシュは、余分のようですが、cshのは、バックスラッシュを付けずに文字列の真っ只中にラインの破壊を許可していないので、そうではありません。
-オペレーティング・システムは、/ binに/ shを 、いくつかのシェルの変形を実行して、ファイルを実行します。 これはあっても-hack!#について知っているが、ちょうどシェルスクリプトとしてASCIIファイルを扱わない古代のシステムのために真です。
-perlの-xは、ファイルを次のように解釈します 
 #!perl -w
 untaint $0; do $0; die $@ if $@; __END__
 garbage
だから、#!の行を尊重しないと、再び現在のファイルを実行します。 これは、エラーの行番号が正しく出てくるようにするとよいでしょう。 
-値をUNTAINTする唯一の方法は、正規表現の部分式のマッチングです。 私たちは=〜/(.*)/ S $ 0それを使用しています。
-$ 0扱いファイルなどの操作を行います。 
 eval 'garbage' if 0;
 eval 'garbage' . q+garbage+ if 0;
 # real Perl code
-$ 0がスクリプト(@INCを超えることの繰り返し処理)の位置については、$ ENV {PATH}を参照してくださいが、時間によって$ 0行いませんが呼び出されません 、$ 0はすでに$ ENV {PATH}の関連成分があれば、それの前に付けていパス検索が行われていたので、@INCには 、ここで検討されることはありません。 $ 0は相対パス名であってもよいが、これはパスサーチので、呼び出されなかったのchdir以来の問題()ではありません。 スクリプト内のインデックス機能がないと、@INCを見て、Perlは組み込みでftp.pl代わりに、私たちの魔法のスクリプトの現在のディレクトリにperlの-x ftp.pl呼び出すときftp.plという名前が分かっているだろうか 。
-($ 0行う呼び出し)前回のリードは__END__トークンでコンパイルを終了しているため、実際のPerlコードは一度だけコンパイルされます。 それは、単一引用符で囲まれた文字列のq +ガベージ+の一部であるため、実際のcompilaionは__END__トークンをバイパスします。
-コンパイルは#を無視する、内側行う発生するため、エラー行番号が正しく報告されています!。 )コンパイル時、マニュアルなどの実行時 ​​にエラーが、(死ぬことを呼び出し、両方のは、$ @文の場合、ダイの$ @によって早期に発見し、報告されています。 実際のPerlコードを一度にコンパイルされるので、各エラーは一度だけ報告されます。
-実際のコードは、任意の出口の数()、execを()、 フォーク()含まれており、(死ぬ)を呼び出し、期待どおりに動作します。サブルーチンの外に返すことがあります 。幸いなことに、純粋なPerlで許可されていませんので、我々は持っていませんこのケースを治療することができます。
-INC @プッシュは、「。」 のperl 5.8.0 -Tによって必要とされます。 

だから、実際のP​​erlコードは、ユーザーがプログラムを起動するどんなに、あっても古いUNIXシステム上で、実行されます。 ヘッダは、CGIスクリプトに含めるのに適しています。 (nonCGIプログラムでは、極端なセキュリティが重要でない場合、-Tオプションの出現を除去することができます。)

ロケール警告なしに完全に次の仕事のすべて、:

 DIR/nice.pl         # preferred
 ash  DIR/nice.pl
 sh   DIR/nice.pl
 bash DIR/nice.pl
 csh  DIR/nice.pl
 tcsh DIR/nice.pl
 ksh  DIR/nice.pl
 zsh  DIR/nice.pl

次の呼び出しは大丈夫です。

 perl -x -S DIR/nice.pl	# locale-warning
 perl DIR/nice.pl	# locale-warning
 perl -x DIR/nice.pl	# locale-warning
 perl -x -S nice.pl	# locale-warning; only if on # $PATH, recommended on Win32
 perl nice.pl		# locale-warning; only from curdir
 perl -x nice.pl	# locale-warning; only from curdir
 nice.pl		# only if on $PATH (or $PATH contains '.')


バギーのPerl 5.004しようとは/ binに実行するので、動作しない、次の/ shの-S nice.pl:

 perl -S nice.pl	# doesn't work 
 perl -S DIR/nice.pl	# doesn't work

もちろん、顕著なパフォーマンスペナルティがあります:/ binに/ shがスクリプトが呼び出されるたびに開始されます。 PERL_BADLANGは perlのが呼び出される前に設定する必要がありますので、これは完全に回避することはできません。 シェルの実行が終了した後、ヘルパーPerlコードの1行が(#!perlの後に)解析され、そしてDOは、ヘルパーコードの5行を解析する原因となります。 これらの6行に費やされる時間とメモリはごくわずかです。 だから、スクリプトの起動を遅くする唯一のアクションは、シェルです。 ユーザーセットと輸出は= xをPERL_BADLANG場合は、高速起動が呼び出すことによって可能です。

 perl -x -S nice.pl
 perl -x DIR/nice.pl

Makefileで、次のように記述する必要があります。

 export PERL_BADLANG=x
 goal:
    perl -x DIR/nice.pl

コマンドラインオプションは-nと- pは 、このヘッダに失敗します。 -nは しばらく の 間(<>){...}内のコードをラップとして実現することができるので、これは深刻な問題ではない、と-pは (<>){...} {印刷を継続しながら、ラッピングに変更することができます}。

***ヘッダーウィザード [#o34aa9d9]

私は自動的に既存のPerlスクリプトにマジックPerlのヘッダーを追加しますヘッダーウィザードを実装しました。 ヘッダーウィザードはhttp://www.inf.bme.hu/~pts/Magic.Perl.Header/ magicc.pl.zipから入手可能です。 作者のサイトからダウンロードすると、あなたは最新バージョンを入手することを保証しても [ 便宜上、我々はまた、http://www.tpj.com/source/でこれを投稿しています。 -ed。]

普遍的に実行可能なPerlスクリプトのための簡単​​レシピ:

+いつものようにあなたのPerlスクリプトを記述します。 あなたが好きなよう()exit()を呼び出して、 死ぬことがあります。
+#を指定します! ...いつものようにperlのライン。 あなたは、任意の数のオプションが、-Tオプション欠落しているか、単独で指定する必要があります(スペースで区切っ)を置いてもよいです。 例:#! /ダミー/ perlの-wi.bak -T。 -Tオプションの詳細についてはperlrun(1)とperlsecを(1)を参照してください。
+スクリプトに右のオプションを含む8行マジックヘッダを付加し、それは(...はchmod + xは)スクリプト・ファイルを実行可能にします。3.ファイル名を指定して実行magicc.pl(ヘッダウィザード)、。 (Perlはそこだけスイッチを探しますので、-Tオプションは、execのperlの秒、およびその他のオプションの両方の後に移動されます。#!perlの後に移動されます。)
+が、コマンドライン上のshまたはperlのではないが、スラッシュでスクリプトを実行します。 たとえば、次のように./my_script.plのarg0 arg1にarg2に 。 あなたが$ PATHにスクリプトを移動した後、ちょうどmy_script.pl arg0の引数1 arg2のようにそれを実行します。 (これは、ロケールの警告を回避し、オプションを有効になります。)これらの呼び出しが何らかの理由でUNIXシステムに障害が発生した場合、私に電子メールにお気軽にお問い合わせください。 クイックフィックスのように、perlの-x -S ./my_script.plのarg0 arg1にarg2にしてスクリプトを実行します。
+Win32システム上で、perlの-x -Sは、スクリプトを実行するための唯一の方法である5.注意してください。 あなたはこれを行い個別の.batファイルを書き込むことができます。
+彼らはそれがあってもドキュメントに従わない人のために働くだろうが高い可能性がありますスクリプトをステップ4で説明した方法を実行する必要があることをユーザーに知らせます。

***結論 [#u73c604d]

このような、広く実装された言語のために、Perlは様々なプラットフォーム上で確実に呼び出すことが驚くほど難しいことができます。 私はこのヘッダーウィザードがちょうど約あらゆるシステム上で最小限の手間で開始されますPerlスクリプトを書くために役立ちます願っています。

TPJ

*Example 1: The Magic Perl Header [#j169cda4]
 #! /bin/sh
 eval '(exit $?0)' && eval 'PERL_BADLANG=x;PATH="$PATH:.";export PERL_BADLANG\
 ;exec perl -T -x -S -- "$0" ${1+"$@"};#'if 0;eval 'setenv PERL_BADLANG x\
 ;setenv PATH "$PATH":.;exec perl -T -x -S -- "$0" $argv:q;#'.q
 #!perl -w
 +push@INC,'.';$0=~/(.*)/s;do(index($1,"/")<0?"./$1":$1);die$@if$@__END__+if 0
 ;#Don't touch/remove lines 1--7: http://www.inf.bme.hu/~pts/Magic.Perl.Header
 # real Perl code begins here