PERLRUN(1) USER COMMANDS PERLRUN(1) NAME perlrun - Perl インタプリタの実行方法 SYNOPSIS perl [switches] filename args DESCRIPTION 実行にあたって、Perl は指定されたスクリプトを以下に示す場所 で探します: 1. コマンドライン上で -e スイッチで指定された行。 2. コマンドライン上で最初のファイル名として示されたファイル の中。 (#! 記法をサポートしているシステムでは、このよう にしてインタプリタを呼び出します。) 3. 標準入力から非明示に渡される。 ファイル名を示す引数が無 い場合にのみうまくいきます。 STDIN からのスクリプトに引 数を渡すには、スクリプト名として明示的に "-" を指定しな くてはなりません、 2 番目、3 番目の方法では、-x スイッチを指定した場合を除いて、 Perl は入力ファイルを最初から解析し始めます。 -x スイッチを 指定した場合には、まず、最初に #! と "perl" という文字列を含 む行を探し、そこから解析を始めます。 これは、大きなテキスト にスクリプトを埋め込んで、実行するようなときに便利です。 (この場合、スクリプトの終わりは、トークン __END__ を使って示 すとよいでしょう。) Perl 5 からは、#! を含む行のスイッチが必ず解析されるようにな りました。 つまり、#! の行で引数が一つしか許されない、ある いはもっと悪く、#! の行が認識されないといったシステムで運用 している場合にも、-x でスクリプトの開始位置を見つけた場合を 含め、どのように Perl が起動されたかによらず、一貫したスイッ チの動作を期待できるようになっています。 多くの OS で、カーネルによる #! 行の解釈が、エラーなしに 32 文字で打ち切られてしまいますので、あるスイッチはコマンドライ ンに渡され、あるスイッチは渡されないといったことが起こります。 注意しないと、文字が続かない "-" だけが渡されるといったこと も起こり得ます。 すべてのスイッチが、32 文字境界の前か後ろ かを確かめたいことでしょう。 多くのスイッチは、余分に処理さ れても問題ありませんが、完全なスイッチの代わりに - が入って いた場合には、スクリプトの代わりに、標準入力を Perl に実行さ せることになってしまいます。 -I スイッチが中途半端になった 場合にもおかしな結果となり得ます。 #! スイッチの解析は、行内で "perl" が示された位置から始まり ます。 とりわけ "-*" と "- " という文字の並びは無視されます ので、 Perl manpages Last change: Release 5.0 Patchlevel 00 1 PERLRUN(1) USER COMMANDS PERLRUN(1) #!/bin/sh -- # -*- perl -*- -p eval 'exec perl $0 -S ${1+"$@"}' if 0; のように書けば、Perl に -p スイッチを渡すことができます。 #! 行に "perl" という語が含まれていなければ、#! の後に指定さ れたプログラムが Perl インタプリタの代わりに実行されます。 これは少し変わっていますが、#! が行なえないマシンを使ってい る方には有効でしょう。 プログラムに対して使っている SHELL が /usr/bin/perl だと言っておけば、Perl が正しいインタプリタ を起動してくれるからです。 スクリプトの場所が特定できたなら、Perl はスクリプト全体を内 部形式にコンパイルし始めます。 コンパイルエラーが見つかった 時には、スクリプトの実行は行なわれません。 (これは、構文エ ラーがある場合にも、途中まで実行される可能性のある、典型的な シェルのスクリプトと異なる点です。) スクリプトが構文的に正しければ、実行されることになります。 スクリプトが、exit() 演算子にも die() 演算子にも当たらないで 最後まで到達すると、正常に完了したことを示すために、暗黙の exit(0) が行なわれます。 スイッチ 1 文字のスイッチは、次に続くスイッチがあれば、それとつなげる ことができます。 #!/usr/bin/perl -spi.bak # -s -p -i.bak と同じ スイッチ一覧: -0digits レコードセパレータ ($/) を 8 進数で示します。 digits を指定しないと、ヌル文字がセパレータになります。 他の スイッチを前に置いてもかまいませんし、digits のあとにつ なげてもかまいません。 たとえば、ファイル名をヌル文字 で区切って表示できる find があれば: find . -name '*.bak' -print0 | perl -n0e unlink のようにできます。 00 という特別な値は、Perl にパラグラフモードで、ファイ ルを読ませます。 0777 という値は、該当する文字がないた め、Perl にファイル全体を読ませることになります。 -a -n や -p といっしょに用いると、自動 split モードになり ます。 -n や -p で作られる暗黙のループ内の最初の文とし て、配列 @F への暗黙の split コマンドが実行されます。 Perl manpages Last change: Release 5.0 Patchlevel 00 2 PERLRUN(1) USER COMMANDS PERLRUN(1) perl -ane 'print pop(@F), "\n";' は、 while (<>) { @F = split(' '); print pop(@F), "\n"; } と等価です。 -F を使って区切文字を変更することができま す。 -c Perl にスクリプトの構文のチェックを行なわせ、実行せずに 抜けるようにします。 -d Perl デバッガの下でスクリプトを実行します。 perldebug manpage を参照してください。 -Dnumber -Dlist デバッグフラグを設定します。 スクリプトがどのように実 行されるかを見るには、-D14 を使ってください。 (これは、 -DDEBUGGING を指定して Perl にデバッグ機能を盛り込んで コンパイルしたときにだけ働きます。) この他に役に立つ値 としては、コンパイルされた構文トリーを表示する、-D1024 があげられます。 -D512 は、コンパイルした正規表現を表 示します。 数字の代わりに文字のリストを指定することも できます (たとえば、-D14 は -Dtls と等価です): 1 p トークン化と構文解析 2 s スタックの表示 4 l ラベルスタックの処理 8 t 実行のトレース 16 o 演算子ノードの構造 32 c 文字列/数値変換 64 P -P のためのプリプロセッサコマンドの表示 128 m メモリ配置 256 f フォーマットの処理 512 r 正規表現の解析 1024 x 構文トリーのダンプ 2048 u 汚染チェック 4096 L メモリリーク (既にサポートされていない) 8192 H ハッシュのダンプ -- values() の横取り 16384 X スクラッチパッドの配置 32768 D 全消去 -e commandline 1 行のスクリプトを指定するのに使用します。 -e が指定さ れると Perl は引数のリストからはスクリプトのファイル名 を探しません。 複数の -e コマンドで、複数行のスクリプ Perl manpages Last change: Release 5.0 Patchlevel 00 3 PERLRUN(1) USER COMMANDS PERLRUN(1) トを構成することができます。 通常のプログラムでセミコ ロンを置くところには、セミコロンを使うことに気を付けて ください。 -Fregexp -a が有効なときに、split を行なう正規表現を指定します。 正規表現の前後に // があっても、そのスラッシュは無視さ れます。 -iextension <> の構文で処理されたファイルを置き換えるための拡張子を 指定します。 これは、入力ファイルをリネームし、元の名 前で出力ファイルを open し、print() 文のデフォルトとし てその出力ファイルを select することで行ないます。 extension が指定されると、昔の内容のバックアップを行な うファイル名の拡張子として、元のファイル名に付け加えら れます。 extension が指定されないと、バックアップを作 りません。 シェルからは $ perl -p -i.bak -e "s/foo/bar/; ... " とすれば、 #!/usr/bin/perl -pi.bak s/foo/bar/; とスクリプトで書くのと同じで、これは、 #!/usr/bin/perl while (<>) { if ($ARGV ne $oldargv) { rename($ARGV, $ARGV . '.bak'); open(ARGVOUT, ">$ARGV"); select(ARGVOUT); $oldargv = $ARGV; } s/foo/bar/; } continue { print; # 元のファイル名に出力する } select(STDOUT); と書くのと、-i の形式が、いつファイル名が変わったかを知 るために、$ARGV と $oldargv を比較する必要がないのを除 いて、同値です。 しかしながら、選択するファイルハンド ルとして ARGVOUT は使用します。 ループのあとは、STDOUT がデフォルトのファイルハンドルとして再設定されます。 個々のファイルの終わりに何かを付け加えたいときや、行番 号をリセットしたいような場合に、個々の入力ファイルの終 わりを知るために、括弧の無い eof を使うことができます。 Perl manpages Last change: Release 5.0 Patchlevel 00 4 PERLRUN(1) USER COMMANDS PERLRUN(1) (perlfunc manpage の eof の項の例を参照してください。) -Idirectory -P といっしょに使って、C プリプロセッサにインクルードフ ァイルを探す場所を示します。 デフォルトでは、 /usr/include と /usr/lib/perl が検索されます。 -loctnum 自動の行末処理を行なうようにします。 これには、2 つの 機能があります。 1 つには、-n や -p を使ったときに、 自動的に行末文字を chomp します。 2 つめに octnum を "$\" に代入し、print 文で行末文字を追加できるようにしま す。 octnum を指定しなかった場合には、その時点の "$/" の値を "$\" に設定します。 たとえば、行を 80 カラムに 切り詰めるには: perl -lpe 'substr($_, 80) = ""' とします。 $\ = $/ という代入は、-l スイッチが処理されるときに実行 されるときに行なわれますので、-l スイッチの後に -0 スイ ッチを置くようにすれば、入力レコードセパレータを、出力 レコードセパレータと違うようにもできます: gnufind / -print0 | perl -ln0e 'print "found $_" if -p' これはまず、$\ に改行 ($/ のデフォルト値) を設定し、そ れから $/ にヌル文字を設定します。 -n 以下のようなループが、実際のスクリプトの回りにあるかの ように Perl に指示します。 sed -n や awk のようにファ イル名引数上で繰り返しを行なうことになります: while (<>) { ... # ここでスクリプトが実行される } デフォルトでは、各行が印字されることはありません。 各 行の印字を行なうには -p を参照してください。 以下にあ げるのは、1 週間以上たったファイルを効率的に削除するも のです: find . -mtime +7 -print | perl -nle 'unlink;' これは、ファイル名が見つかるごとにプロセスを起動しなく て済みますので、find の -exec スイッチを使うよりも速く なります。 Awk と同じように、暗黙に実行されるループの前後に実行さ れるコードを指定するために、BEGIN ブロックと END ブロッ クを使うことができます。 Perl manpages Last change: Release 5.0 Patchlevel 00 5 PERLRUN(1) USER COMMANDS PERLRUN(1) -p 以下のようなループが、実際のスクリプトの回りにあるかの ように Perl に指示します。 sed のようにファイル名引数 上で繰り返しを行なうことになります: while (<>) { ... # ここでスクリプトが実行される } continue { print; } 各行は、自動的に印字されることになります。 印字を抑制 するには、-n スイッチを使ってください。 -p は -n スイ ッチを無効にします。 Awk と同じように、暗黙に実行されるループの前後に実行さ れるコードを指定するために、BEGIN ブロックと END ブロッ クを使うことができます。 -P Perl によるコンパイルを行なう前に、スクリプトを C プリ プロセッサにかけるようにします。 (コメントも CPP のデ ィレクティブも # で始まりますから、コメントの最初を C プリプロセッサが認識してしまう "if", "else", "define" といった単語で始めるべきではありません。) -s コマンドライン上のスクリプト名の後から、ファイル名引数 (または --) の前までのスイッチのための、原始的な解析を 行なえるようにします。 ここで見つかったスイッチは、 @ARGV から取り除かれ、対応する Perl スクリプトの変数に 設定されます。 以下のスクリプトは、-xyz というスイッチ を付けて実行された時にだけ、"ture" と表示するものです。 #!/usr/bin/perl -s if ($xyz) { print "true\n"; } -S Perl がスクリプトを探すときに環境変数 PATH を参照するよ うにします (スクリプト名がスラッシュで始めるときを除き ます)。 これは、#! をサポートしていないマシンで、#! に よる実行をエミュレートするために、以下のようにして使い ます: #!/usr/bin/perl eval "exec /usr/bin/perl -S $0 $*" if $running_under_some_shell; システムは、最初の行を無視し、スクリプトを /bin/sh に渡 し、/bin/sh は Perl スクリプトをシェルスクリプトとして実 行しようとします。 シェルは 2 行目を通常のシェルコマン ドとして実行し、Perl インタプリタを起動することになりま す。 $0 にフルパス名が入っているとは限らないシステムも ありますので、-S が Perl に必要に応じてスクリプトを探す ように指示します。 Perl がスクリプトを見つけると、これ Perl manpages Last change: Release 5.0 Patchlevel 00 6 PERLRUN(1) USER COMMANDS PERLRUN(1) らの行の解析を始めますが、$running_under_some_shell が 真になることがないため、無視することになります。 $* を 使うよりもファイル名内に埋め込まれたスペースなどを扱う ことのできる ${1+"$@"} の方がよいのですが、スクリプトが csh で解釈される場合には、うまくいきません。 csh では なく、sh を起動するように、いくつかのシステムでは、#! の行を Perl も無視することになっている、コロンだけの行 で置き換える必要があるかもしれません。 そういった制御 が効かないシステムでは、csh でも sh でも Perl でも使え る、回りくどい方法を使うことが必要です: eval '(exit $?0)' && eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' & eval 'exec /usr/bin/perl -S $0 $argv:q' if 0; -T 「汚染」チェックをオンにします。 通常、このチェックは setuid や setgid のスクリプトを実行するときにだけ、行な われます。 perlsec manpage を参照してください。 -u スクリプトのコンパイル後、コアダンプを行なうようにしま す。 このコアダンプを持ってきて、(Perl の配布では提供 されていませんが) undump プログラムを使って、実行ファイ ルに変換することができます。 これは多少ディスク容量を 食いますが (実行ファイルを sprit することで少しは減りま す)、実行開始を速くすることができます。 (減らしても、 "hello world" の実行ファイルは、私のマシンで 200K 程に なります。) ダンプする前に部分的にスクリプトを実行して おきたい場合には、このスイッチの代わりに dump() 演算子 を使ってください。 undump が実行できるのは特定の環境下 ですし、これが使えない移植バージョンの Perl もあるでし ょう。 -U Perl に安全でない演算を許可します。 現在のところ、「安 全でない」演算には、スーパーユーザとして実行中にディレ クトリを削除することと、致命的な汚染チェックを警告に替 えて、setuid プログラムを実行することが含まれます。 -v Perl 実行ファイルのバージョンとパッチレベルを表示します。 -w 1 度しか使われない識別子、設定される前に使われている変 数に警告を出します。 サブルーティンの再定義、未定義の ファイルハンドルの参照や、read-only でオープンしたファ イルハンドルへの書き込みにも警告を出します。 また、数 値に見えない値を数値として使った場合、配列をスカラであ るかのように使った場合、100 段階以上のサブルーティンの 再帰、その他たくさんの事に警告を出します。 perldiag manpage と perltrap manpage を参照してください。 -x directory テキスト中にスクリプトが埋め込まれている事を Perl につ たえます。 最初の #! で始まり、"perl" という文字列を含 Perl manpages Last change: Release 5.0 Patchlevel 00 7 PERLRUN(1) USER COMMANDS PERLRUN(1) む行までの、先行するゴミは捨てられます。 その行にある 意味を持つスイッチは、(通常の #! 処理と同じく 1 つのま とまりだけですが) 適用されます。 directory が指定され ると、Perl はスクリプトの実行前に、そのディレクトリに移 ります。 -x スイッチは先行するゴミの処分を制御するだけ です。 スクリプトの後に無視すべきゴミがある場合には、 __END__ でスクリプトを終了する必要があります (その、後 に続くゴミの一部または全部は、必要に応じて DATA ファイ ルハンドルを通して、そのスクリプトで処理する事ができま す)。 Perl manpages Last change: Release 5.0 Patchlevel 00 8