3-2.A Magic Header for Starting Perl Scripts 日本語訳 のバックアップ差分(No.3)


  • 追加された行はこの色です。
  • 削除された行はこの色です。
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スクリプトを取り扱うように指示しています。 この最初のー行の概念は単純ですが、それを普遍的に適用できるように書くのは非常に困難になる傾向です。
ほとんどの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 / perlのである上に、ほとんどのSolarisシステムとの互換性を中断します。 悪いニュースは、#の後に指定するperlのための標準的な場所がないことです!。 さらに悪いことに、一部の古いUNIXシステムは#!行に指定することができますどのように非常に厳格なルールを課します。 その結果、あなたは間に選択することができます:
たとえば、'''#! /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のinstall.plを入力すると、おそらく。)
    どこでも動作するソリューションを見つけます。 
この記事では最後のオプション-マジックPerlヘッダー、任意のUNIXオペレーティング・システム上でPerlスクリプトを起動するための複数行のソリューションについて説明します。

この記事では最後のオプション・マジック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 -wT'''の記述は、動作しません。
-'''#! /usr/bin/env perl -wT'''の記述は、動作しません。
-'''#! /usr/bin/env perl'''の記述は、動作しません。

    指定#!/ usr / local / bin / perlの-w -TいくつかのUNIXオペレーティング・システムは、#の後にのみ、単一のコマンドラインスイッチを可能にするので動作しません!。 このワンライナーは、Linux上で動作しません。
    いくつかのUNIXオペレーティング・システムは、#の後にスペースを期待するため、#!/ usr / local / bin / perlの-WTを指定すると、動作しません!。 このワンライナーは/ usr / local / bin / perlが存在する場合にのみLinux上で動作します(ただし、通常はしません)。
    
    #を指定します! / usr / local / bin / perlの-WT perlはそのようなDebianのLinux上のように、 は/ usr / binにまたはどこか他の場所に存在する可能性がありますので、動作しません。 (注意:スクリプトのユーザーはperlのバイナリを見つけて、それに応じて、スクリプトの最初の行を変更することができることは十分に教育を受けられない場合があり、そしていくつかのセキュリティ構成では、彼らはそれを行うためのアクセス許可を持っていない可能性があり、場合でも、彼らは変更するには、正確に何を知っています。)このワンライナーはほとんどアウトオブボックスのLinux上で動作しません。
    #を指定します! 一部のUNIXオペレーティング・システムでは、#の後に絶対的な実行可能ファイル名(/で始まる)を期待するためのperl -WTは動作しません!。 このワンライナーは、Linux上では動作しません。
    #を指定します! / usr / binに/ envをperlのいくつかのシステムでは、コマンド名の後にのみ、ゼロまたは1つの引数を可能にするので-WTは動作しません。 (また、いくつかのシステムでは、最初の全体の長さには限界がある行は、それが32または64文字限り少ないことができます。)コマンドライン以外の場所からの-Tスイッチを指定することは非常に難しいだろう。 (-wスイッチが容易である:ちょうどBEGIN書き込み{W $ ^ = 1} Perlコードの前に)-Tスイッチは、セキュリティスイッチであり、遅すぎる、それを指定すると、悪質な事故のためにバックドアを開きます。 あなた(プログラマ)はここに非常に注意する必要がありますが、正しいスイッチを指定する場所がないので、それは困難です。 このワンライナーは、Linux上では動作しません。
    #を指定します! ENVが見つからないか、いくつかのシステム上の他の場所に配置される可能性があるために/ usr / binに/のenv perlは 、いずれか、動作しません。 このワンライナーは、Linux上で動作します。 


    Specifying #! /usr/local/bin/perl -wT doesn't work because perl might be located in /usr/bin or somewhere else, such as on Debian Linux. (Remember: The user of your script may not be educated enough to be able to find the perl binary and modify the first line of the script accordingly; and in some security configurations, they may not have the permission to do it, even when they know exactly what to change.) This one-liner rarely works on out-of-the-box Linux.
    Specifying #! perl -wT doesn't work because some UNIX operating systems expect an absolute executable name (starting with /) after #!. This one-liner doesn't work on Linux.
    Specifying #! /usr/bin/env perl -wT doesn't work because some systems allow only zero or one argument after the command name. (Moreover, in some systems there is a limit for the overall length of the first line—it can be as few as 32 or 64 characters.) It would be very hard to specify the -T switch from anywhere other than the command line. (The -w switch is easier: just write BEGIN{$^W=1} in front of the Perl code.) The -T switch is a security switch, and specifying it too late opens the backdoor for malicious accidents. You (the programmer) should be extremely careful here, but it is difficult because there is no place to specify the correct switches. This one-liner doesn't work on Linux.
    Specifying #! /usr/bin/env perl doesn't work, either, because env might be missing or located somewhere else on some systems. This one-liner works on Linux. 

マジックPerlのヘッダーを構築

スクリプトを実行するPerlを起動するには、noポータブルな方法がないため問題に対するシングル#!-lineソリューションは、一般的なケースでは存在しないことは明らかです。 複数行の溶液が必要となります。 このセクションでは、私はこのソリューションを構築するために開始されます。 私は道に沿って問題と制限を特定し、次のセクションでは、あなたが任意のUNIXシステム上でPerlスクリプトを起動することができます最終的に、完全な魔法のヘッダーを提示します。

スクリプトのための唯一のポータブル始まりです。

  #!  / binに/ shを 

/ binに/ shが 、すべてのUNIXシステムで提供されていますが、それは、とCシェルの変種(例えばpdkshのとzshのような)Kornシェルの変種(例えば(例えばバッシュや灰など)Bourneシェルの変異体を含む、任意のシェルへのシンボリックリンクであるかもしれません)CSHやtcshのよう。 多くのUNIXユーティリティ、およびlibcのシステム(3)関数(ANSI C、POSIX.2、BSD 4.3に準拠)は、作業/ binに/ shのに依存しています。 だから、/ binに/ SHが存在し、Bourneシェル、Kornシェル、またはCシェルの変種であると仮定することは、かなり合理的です。 Linuxでは、/ binに/ shが 、通常は/ binに/ bashのへのシンボリックリンクです。 (Linuxのディスクをインストールするには、それは時々 ビン/灰/へのシンボリックリンクまたは内蔵BusyBoxのの灰である。)のWin32のMinGW MSYS上で、/ binに/ shが bashのです。しかし、/ binに/ bashはありません。 Solarisでは、/ binに/ shが Sunの独自の単純化のBourne shellのクローンで、デジタルUNIXでは、/ binに/ shの中で簡単なのBourneシェルのクローンを持っています。 (ライン#/ binに/ shを- !それはtcshの場合は、のためにエラーになりますので、実行可能ファイルの任意のファイル名はここでは動作しません可能にするために、多くのシェルスクリプトに見られる- 。スイッチ)

私たちは、$ PATHにperlの実行ファイルを検索し、正しいスイッチとそれを実行する簡単なシェルラッパーを書くことができます。 実際には、これは、これは.BATバッチファイルを使用して、Win32システム上で動作することが唯一の方法です。 解決のための候補者は次のとおりです。

  ##ファイルmy_script.sh、バージョン1#!  / binに/ shのperlのmy_script.pl ##ファイルmy_script.plの#実際のPerlコードはここから始まります 

これは、以下のような問題があります。

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

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

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

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

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

  ##ファイルmy_script.sh、バージョン2#!  / binに/ shをexecのperlの-S  -  my_script.plの "$ @" 

(このようなGNUバッシュ、灰、zshの、pdkshの、およびSolaris / binに/ shのような)すべてのBourneシェルとKornシェルが正しくmy_script.shを解釈することができます。 しかし、Cシェルは「変更されていない、シェルに渡されるすべての引数。 "のための異なる表記を使用します Q の代わりに"$ @を":彼らは$ ARGVを使用しています。 perlrun(1)マニュアルページがCシェルを検出し、思い出に残る構造物を説明します。

  evalを '(終了$?0')&&はeval "エコー" KornシェルとBourneシェル " 'エコーすべて 

メッセージには、「 すべて 」すべての3つのシェルのタイプにエコーされますが、唯一のKornシェルとBourneシェルシェルは「Kornシェルとボーン 」のメッセージを印刷します。 (zshのでは、結果は$?の値に依存しますが、zshのは、我々が使用CSHとBourneシェル構文の両方を理解するので、それは問題は発生しません。)ここでのトリックは$は?前回の終了ステータスであるということですCシェルの初期値が0の場合、しかし、$?0のコマンドは、変数$ 0が存在するため、「1」を返しますテストです。

私たちは、perlのEXECコマンドへの Cシェル検出コードにエコーを変更することができますし、それはそれです。

  ##ファイルmy_script.sh、バージョン3#!  / binに/のshのeval '(終了$ 0≦)' &&のexecのperl -S  -  "$ 0"の "$ @"実行するperl -S  -  "$ 0" $のARGV:Q 

今、私たちは私たちのウィザードの最初の手順を行う準備ができている:シェルから実行したときにPerlを使用して自分自身を呼び出す単一のファイルの中にmy_script.plとmy_script.shを組み合わせます。 (後でそれに取得瞬間-we'llは、csh互換性を忘れます。)

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

  #!  / binに/ shのevalの「エコーDEBUG。 幹部のperl -S $ 0 $ {1 + "$ @"} '0の場合。  #実際のPerlコードはここから始まります 

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

次の簡単なトリックでは、(1)のマニュアルページはperlrunによって提案された、我々は最初の行にあるワードのperlが含まれています。

  #!  / binに/ shの - # -  *  -  perlの -  *  -  evalを 'execのperlの-S $ 0 $ {1 + "$ @"}' 0の場合。  #実際のPerlコードはここから始まります 

( - #* - *のperl - * - 、./my_script.pl / binに/ shを 、)、およびシェルが不快なエラー・メッセージが表示されますOSはコマンドラインを起動しますので、これは、Linuxを含む多くのシステム上で動作するように失敗します完全に偽のスイッチに関する。

だから我々は最初の行を省略することができます。

  0の場合はeval」のexec perlは$ 0 $ {1 + "$ @"}を-S ';  #実際のPerlコードはここから始まります 

このソリューションは、トーマス・エッサーのepstopdfユーティリティに触発され、perlのmy_script.plと./my_script.plの両方でLinuxシステム上で動作しているようです。 しかし、私たちはより良い行うことができます。 このスクリプト内の主要な欠陥は、オペレーティング・システムはスクリプトなどのASCII文字で始まる実行可能ファイルを認識し、/ binに/ shを介してそれらを実行しているという事実に依存しているということです。 いくつかのシステムでは、発生する可能性がある」、「バイナリファイル '' Execのフォーマットエラーまたは実行できません " '。

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

解決策は、別の問題があります:誰かがスクリプトになどにスペースや他の変な文字、との奇妙なファイル名を与えた場合

  -eシステム(停止) 

その後、コマンド

  perlの-S -eシステム(停止) 

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

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

  #!  / binに/のshのeval 'execをperlの-S -x  -  "$ 0" $ {1 + "$ @"}' 0の場合。  #!perlの-w#実際のPerlコードはここから始まります 

ここでのトリックは、-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場合($のsecond_run!){$ second_run = 1;  ($ 0)を行います。  $ @ダイの場合の$ @; 出口 } } 

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

  {BEGIN場合($のsecond_run!){$ second_run = 1;  ($ 0)を行います。  $ @ダイの場合の$ @; 出口は}} 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を変えるチャンスを持っている長い前に警告を発します。
完成ヘッダー

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

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

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

      #!  / binに/ shを - 真&&のeval '...。 幹部のperl -T -x -S "$ 0"#{1 + "$ @"} '#コメントごみ 

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

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

      #!  / binに/ shの - 偽&&のeval '...';  evalの '...。 幹部のperl -T -x -S  -  "$ 0" $ ARGV:Q '#コメントごみ 

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

    ヘッダーの2行目の最後のバックスラッシュは、余分のようですが、cshのは、バックスラッシュを付けずに文字列の真っ只中にラインの破壊を許可していないので、そうではありません。
    オペレーティング・システムは、/ binに/ shを 、いくつかのシェルの変形を実行して、ファイルを実行します。 これはあっても-hack!#について知っているが、ちょうどシェルスクリプトとしてASCIIファイルを扱わない古代のシステムのために真です。
    perlの-xは、ファイルを次のように解釈します 

      #!perlの-w UNTAINT $ 0;  $ 0行います。  $ @ダイの場合の$ @;  __END__ごみ 

    だから、#!の行を尊重しないと、再び現在のファイルを実行します。 これは、エラーの行番号が正しく出てくるようにするとよいでしょう。 

    値をUNTAINTする唯一の方法は、正規表現の部分式のマッチングです。 私たちは=〜/(.*)/ S $ 0それを使用しています。
    $ 0扱いファイルなどの操作を行います。 

      0の場合はeval 'ごみ';  evalの「ごみ」。  Q +ゴミ+ 0の場合。  #実際のPerlコード 

    $ 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#好適灰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#ロケール警告perlのDIR / nice.pl#ロケール警告perlはDIR / nice.pl#ロケール警告のperl -x -S nice.pl#ロケールに警告を-x; のみの#$ PATH上の場合、Win32のperlのnice.pl#ロケール警告にお勧めします。  CURDIRのperl -x nice.pl#ロケール警告からのみ。  (PATHが含まれているか、$ '。')CURDIR nice.pl#のみの$ PATH上の場合からのみ 

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

  perlの-S nice.pl#perlの-S DIR動作しない/ nice.pl#は動作しません。 

もちろん、顕著なパフォーマンスペナルティがあります:/ 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で、次のように記述する必要があります。

 輸出PERL_BADLANG = Xゴールます。perl -x DIR / nice.pl 

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

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

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

1.いつものようにあなたのPerlスクリプトを記述します。 あなたが好きなよう()exit()を呼び出して、 死ぬことがあります。

2.#を指定します! ...いつものようにperlのライン。 あなたは、任意の数のオプションが、-Tオプション欠落しているか、単独で指定する必要があります(スペースで区切っ)を置いてもよいです。 例:#! /ダミー/ perlの-wi.bak -T。 -Tオプションの詳細についてはperlrun(1)とperlsecを(1)を参照してください。

スクリプトに右のオプションを含む8行マジックヘッダを付加し、それは(...はchmod + xは)スクリプト・ファイルを実行可能にします。3.ファイル名を指定して実行magicc.pl(ヘッダウィザード)、。 (Perlはそこだけスイッチを探しますので、-Tオプションは、execのperlの秒、およびその他のオプションの両方の後に移動されます。#!perlの後に移動されます。)

4.が、コマンドライン上の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ファイルを書き込むことができます。

6.彼らはそれがあってもドキュメントに従わない人のために働くだろうが高い可能性がありますスクリプトをステップ4で説明した方法を実行する必要があることをユーザーに知らせます。
結論

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

TPJ