perlrun - Perl インタプリタの起動方法
perl [ -sTtuUWX ] [ -hv ] [ -V[:configvar] ] [ -cw ] [ -d[t][:debugger] ] [ -D[number/list] ] [ -pna ] [ -Fpattern ] [ -l[octal] ] [ -0[octal/hexadecimal] ] [ -Idir ] [ -m[-]module ] [ -M[-]'module...' ] [ -f ] [ -C [number/list] ] [ -S ] [ -x[dir] ] [ -i[extension] ] [ [-e|-E] 'command' ] [ -- ] [ programfile ] [ argument ]...
Perl プログラムを実行する普通の方法は、直接実行できる形にするか、 コマンドラインの引数としてソースファイルの名前を渡すことです。 (対話的な Perl 環境もあります -- どのようにするかの詳細については perldebug を参照して下さい。) 実行にあたって、Perl は指定されたプログラムを以下に示す場所で 探します:
コマンドライン上で -e か -E のスイッチで指定された行。
コマンドライン上で最初のファイル名として示されたファイルの中。 (#! 記法をサポートしているシステムでは、このようにして インタプリタを呼び出します。 "Location of Perl" を参照して下さい。)
標準入力から暗黙に渡される。 ファイル名を示す引数が無い場合にのみうまくいきます。 STDIN から読み込むプログラムに引数を渡すには、 プログラム名として明示的に "-" を指定しなくてはなりません、
2 番目、3 番目の方法では、-x スイッチを指定した場合を除いて、 Perl は入力ファイルを最初から解析し始めます。 -x スイッチを 指定した場合には、まず、最初に #! と "perl" という文字列を 含む行を探し、そこから解析を始めます。 これは、大きなテキストにプログラムを埋め込んで、実行するようなときに便利です。 (この場合、プログラムの終わりは、トークン __END__
を使って 示すとよいでしょう。)
#! を含む行のスイッチが必ず解析されるようになりました。 つまり、#! の行で引数が一つしか許されない、あるいはもっと悪く、 #! の行が認識されないといったシステムで運用している場合にも、-x で プログラムの開始位置を見つけた場合を含め、どのように Perl が起動されたかに よらず、一貫したスイッチの動作を期待できるようになっています。
歴史的なオペレーティングシステムの中にはカーネルによる #! 行の解釈が、 エラーなしに 32 文字で打ち切られてしまうものがありますので、あるスイッチは コマンドラインに渡され、あるスイッチは渡されないといったことが起こります。 注意しないと、文字が続かない "-" だけが渡されるといったことも 起こり得ます。 すべてのスイッチが、確実に 32 文字境界の前か後ろかのどちらかに なるようにしたいことでしょう。 多くのスイッチは、余分に処理されても問題ありませんが、完全なスイッチの 代わりに "-" が入っていた場合には、プログラムの代わりに、標準入力を Perl に 実行させることになってしまいます。 -I スイッチが中途半端になった場合にもおかしな結果となり得ます。
2 回実行されることに注意する必要のあるスイッチもあります。 例えば -l と -0 の組み合わせです。 (可能なら) 両方のスイッチが 32 文字境界の後ろにいくようにするか、 -0digits を BEGIN{ $/ = "\0digits"; }
で置き換えてください。
#! スイッチの解析は、行内で "perl" が示された位置から始まります。 とりわけ "-*" と "- " という文字の並びは無視されますので、以下のように 書くと:
#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS $0 ${1+"$@"}'
if 0;
Perl に -p スイッチを渡すことができます。
似たようなトリックは(持っていれば) env プログラムでも使えます。
#!/usr/bin/env perl
上の例は Perl インタプリタに相対パスを使って、 ユーザーの PATH で最初にあったバージョンを使います。 もし特定のバージョンの Perl、例えば perl5.005_57 が使いたいなら、 #! 行のパスに直接書くべきです。
#! 行に "perl" という語が含まれていなければ、#! の後に指定された プログラムが Perl インタプリタの代わりに実行されます。 これは少し変わっていますが、#! が行なえないマシンを使っている方には 有効でしょう。 プログラムに対して使っている SHELL が /usr/bin/perl だと言っておけば、 Perl が正しいインタプリタを起動してくれるからです。
プログラムの場所が特定できたなら、Perl はプログラム全体を内部形式に コンパイルし始めます。 コンパイルエラーが見つかった時には、プログラムの実行は行なわれません。 (これは、構文エラーがある場合にも、途中まで実行される可能性のある、 典型的なシェルのスクリプトと異なる点です。)
プログラムが構文的に正しければ、実行されることになります。 プログラムが、exit() 演算子にも die() 演算子にも当たらないで最後まで 到達すると、正常に完了したことを示すために、暗黙の exit(0)
が 行なわれます。
Unix の #! のテクニックは他のシステムでもシミュレートされています。
以下のように
extproc perl -S -your_switches
*.cmd
ファイルの最初の行に書いてください (-S は cmd.exe の `extproc' の扱いのバグを引き起こします)。
プログラムを実行するバッチファイルを作って、ALTERNATE_SHEBANG
で コード化してください (さらなる情報についてはソース配布パッケージの dosish.h ファイルを参照して下さい)。
Win95/NT でのインストールにおいて、ActiveState の Perl 用インストーラを 使った場合は、拡張子 .pl を Perl インタプリタに関連付けるよう レジストリを変更します。 他の方法で Perl をインストールした場合(ソースから構築した場合を含みます)、 レジストリを自分で変更する必要があります。 これは実行可能な Perl プログラムと Perl ライブラリファイルとの 違いがなくなってしまうことに注意してください。
以下のように
$ perl -mysw 'f$env("procedure")' 'p1' 'p2' 'p3' 'p4' 'p5' 'p6' 'p7' 'p8' !
$ exit++ + ++$status != 0 and $exit = $status = undef;
プログラムの先頭に書いてください。 ここで -mysw は Perl に渡したいコマンドラインスイッチです。 これで perl program
として直接プログラムを起動できますし、 @program
として(あるいは DCL$PATH 経由でプログラム名を使って) DSL 手続きとして起動できます。
この決まり文句は覚えるには少々長すぎますが、perl "-V:startperl"
とすれば Perl がこれを表示してくれます。
非 Unix システムのコマンドインタプリタはクォートに関して Unix シェルと異なった考え方をしています。 お使いのコマンドインタプリタの特殊文字について (*
, \
, "
は 一般的です)、そして一行で起動するために(後述する -e を参照して下さい) 空白や特殊文字を保護する方法について学ぶ必要があるでしょう。
システムによってはシングルクォートをダブルクォートに変更する必要が あるかもしれません。 しかし Unix や Plan9 のシステムでは してはいけません。 また、単体の % を %% に変更する必要があるかもしれません。
例えば:
# Unix
perl -e 'print "Hello world\n"'
# MS-DOS, etc.
perl -e "print \"Hello world\n\""
# VMS
perl -e "print ""Hello world\n"""
問題は、これらはどれも信頼性がないことです。 これはコマンドに依存し、どれも動かないかもしれません。 4DOS がコマンドシェルなら、おそらくよりよく動きます:
perl -e "print <Ctrl-x>"Hello world\n<Ctrl-x>""
Windows NT の CMD.EXE は誰も見ていない間に多くの標準 Unix 機能が 入り込んでいますが、クォートのルールに関しては ドキュメントを探してみてください。
この辺りのことに関する一般的な解決方法はありません。 まったくぐちゃぐちゃです。
当たり前のように聞こえるかもしれませんが、 Perl はユーザーが簡単に発見できる場合にのみ有用です。 可能なら、/usr/bin/perl と /usr/local/bin/perl の両方に 実際のバイナリへのシンボリックリンクを置くというのはよい考えです。 もしこれが無理なら、システム管理者は Perl と付随するユーティリティ (への シンボリックリンク) を、典型的にユーザーの PATH で見付かるディレクトリか、 その他の明らかで便利な場所に置くべきです。
このドキュメントでは、#!/usr/bin/perl
とプログラムの先頭に書けば システムの全てのメソッドが実行できるものとしています。 特定のバージョンを使いたい場合は、特定のパスを使うか:
#!/usr/local/bin/perl5.00554
あるいは単に最低限のバージョンを指定した場合は、 以下のような行をプログラムの先頭に置いてください:
use 5.005_54;
全ての標準コマンドと同様に、1 文字のスイッチは、次に続くスイッチが あれば、それとつなげることができます。
#!/usr/bin/perl -spi.orig # same as -s -p -i.orig
スイッチ一覧:
入力レコードセパレータ ($/
) を 8 進数または 16 進数で示します。 digits を指定しないと、ヌル文字がセパレータになります。 他のスイッチを前に置いてもかまいませんし、digits のあとに つなげてもかまいません。 たとえば、ファイル名をヌル文字で区切って表示できる find があれば:
find . -name '*.orig' -print0 | perl -n0e unlink
00 という特別な値は、Perl にパラグラフモードで、ファイルを読ませます。 0777 という値は、該当するバイトがないため、 Perl にファイル全体を読ませることになります。
Unicode 文字を指定したい場合は、16 進数のフォーマット -0xHHH...
を 使ってください。 ここで H
は 16 進数として有効な文字です (これは -x
で 16 進数の数値からなるディレクトリ名を指定できない ことを意味します)。
-n や -p といっしょに用いると、自動 split モードになります。 -n や -p で作られる暗黙のループ内の最初の文として、 配列 @F への暗黙の split コマンドが実行されます。
perl -ane 'print pop(@F), "\n";'
は以下のものと等価です。
while (<>) {
@F = split(' ');
print pop(@F), "\n";
}
-F を使って区切文字を変更することができます。
-C
フラグは Perl Unicode 機能のいくつかを制御します。
5.8.1 から、-C
フラグは数値またはオプション文字のリストを つけることが出来ます。 指定可能な文字と数値およびその効果は以下の通りです; 文字のリストは数値の合計と同じです。
I 1 STDIN は UTF-8 と仮定する
O 2 STDOUT は UTF-8 と仮定する
E 4 STDERR は UTF-8 と仮定する
S 7 I + O + E
i 8 UTF-8 は入力ストリームのデフォルト PerlIO 層
o 16 UTF-8 は出力ストリームのデフォルト PerlIO 層
D 24 i + o
A 32 @ARGV の要素は UTF-8 でエンコードされた文字列と推測する
L 64 通常は "IOEioA" は無条件ですが、
L はロケール環境変数(LC_ALL, LC_TYPE, LANG, 優先度順)によって
条件付きとなります -- もし変数が UTF-8 を示していれば、
選択された "IOEioA" が有効になります
a 256 デバッグモードで UTF-8 キャッシュコードを実行するために、
${^UTF8CACHE} を -1 にセットする。
例えば、-COE
と -C6
はどちらも STDOUT と STDERR を UTF-8 化します。 同じ文字を繰り返しても冗長なだけで、加算されたりトグルになったりはしません。
io
オプションは引き続く open() (あるいは同様の I/O 操作) において 暗黙的に :utf8
PerlIO 層が適用されます。 言い換えると、入力ストリームでは UTF-8 が想定され、出力ストリームは UTF-8 で出力されます。 これは単にデフォルトであり、通常どおり open() と binmode() で明示的に 変更できます。
-C
が単体で(数値やオプションリストなし)起動されるか、 PERL_UNICODE
環境変数が空文字列 ""
の場合、-CSDL
と 同じ効果となります。 言い換えると、標準 I/O 操作とデフォルトの open()
層はロケール環境変数が UTF-8 ロケールを示している場合 のみ UTF-8 化されます。 この振る舞いは Perl 5.8.0 での 暗黙の (そして問題のある) UTF-8 に 関する振る舞いと同じです。
-C0
(あるいは PERL_UNICODE
に "0"
) を指定すると 明示的に上記の全ての Unicode 機能を無効にします。
読み込み専用のマジック変数 ${^UNICODE}
にこの設定の数値表現が 反映されます。 これは Perl 起動時にセットされる変数で、読み込み専用です。 実行中に効果を得たい場合は、3 引数の open() ("open" in perlfunc 参照), 2 引数の binmode() ("binmode" in perlfunc 参照), open
プラグマ (open 参照) を使ってください。
(5.8.1 以前の Perl では -C
スイッチは Win32 専用のスイッチで、 Unicode 対応の "ワイド文字システムコール" Win32 API を使うためのものでした。 この機能は事実上使われませんでしたが、コマンドラインスイッチは "再利用" されました。)
注意: perl 5.10.1 から、-C スイッチが #! 行で使われると、 コマンドラインでも指定しなければなりません; なぜなら標準ストリームは perl インタプリタ実行のこの地点で既に設定されているからです。 I/O ストリームのエンコーディングの設定に binmode() も使えます。
Perl にスクリプトの構文のチェックを行なわせ、実行せずに 終了するようにします。 実際には、BEGIN
, UNITCHECK
, CHECK
, use
ブロックは 実行します。 これらはプログラムの実行の外側にあるものと考えられるからです。 INIT
と END
ブロックはスキップされます。
Perl デバッガの下でプログラムを実行します。 perldebug を参照してください。 t が指定されると、デバッグするコードがスレッドを使っていることを デバッガに示します。
Devel::foo としてインストールされる デバッグ・プロファイリング・ トレースモジュールの制御下でプログラムを実行します。 つまり、-d:DProf は Devel::DProf プロファイラを使って プログラムを実行します。 -M フラグと共に使うと、オプションは Devel::foo パッケージに渡され、 Devel::foo::import ルーチンで解釈されます。 オプションをコンマ区切りのリストにするときは =
の文字の後に 続けなければなりません。 t が指定されると、デバッグするコードがスレッドを使っていることを デバッガに示します。 perldebug を参照して下さい。
デバッグフラグを設定します。 スクリプトがどのように実行されるかを見るには、-Dtls を使ってください。 (これは、デバッグ機能を盛り込んでコンパイルしたときにだけ働きます。) この他に役に立つ値としては、コンパイルされた構文ツリーを表示する、 -Dx があげられます。 -Dr は、コンパイルした正規表現を表示します。 出力形式については perldebguts に説明があります。
文字のリストの代わりに数字を指定することもできます (たとえば、-D14 は -Dtls と等価です):
1 p トークン化と構文解析 (v と併用されると、パーススタックの表示)
2 s スタックの表示 (v と併用されると、全てのスタックの表示)
4 l コンテキスト(ループ)スタックの処理
8 t 実行のトレース
16 o メソッドとオーバーロードの解決
32 c 文字列/数値変換
64 P プロファイリング情報、ソースファイル入力状態の表示
128 m メモリと SV の配置
256 f フォーマットの処理
512 r 正規表現の解析と実効
1024 x 構文トリーのダンプ
2048 u 汚染チェック
4096 U 非公式な、ユーザーハック (プライベートな、リリースされない利用法のために予約)
8192 H ハッシュのダンプ -- values() の横取り
16384 X スクラッチパッドの配置
32768 D 全消去
131072 T トークン化
262144 R ダンプされた変数のリファレンスカウントを含む(-Dsのとき)
524288 J DB パッケージの中では s,t,P デバッグコードを実行しない
1048576 v 詳細: 他のフラグと組み合わせて使う
2097152 C コピーオンライト
4194304 A 内部構造の一貫性チェック
8388608 q 静粛 - 現在のところ "EXECUTING" メッセージだけを抑制する
16777216 M スマートマッチングの解決をトレース
33554432 B BEGIN のような特殊ブロックを含む、suBroutine 定義のダンプ
これらの全てのフラグは Perl 実行ファイルをコンパイルするときに -DDEBUGGING が指定されている必要があります (但しこれを変更するときは Devel::Peek, re を参照してください)。 そうするためにどうすればいいかについては Perl のソース配布パッケージの INSTALL ファイルを参照して下さい。 このフラグは Configure
が最適化/デバッガフラグを尋ねたときに -g オプション込みで指定すれば自動的にセットされます。
シェルスクリプトにおける sh -x
のように、単に今実行している Perl の コードを表示したい場合は、Perl の -D スイッチは使えません。 代わりに以下のようにしてください:
# If you have "env" utility
env PERLDB_OPTS="NonStop=1 AutoTrace=1 frame=2" perl -dS program
# Bourne shell syntax
$ PERLDB_OPTS="NonStop=1 AutoTrace=1 frame=2" perl -dS program
# csh syntax
% (setenv PERLDB_OPTS "NonStop=1 AutoTrace=1 frame=2"; perl -dS program)
詳細とバリエーションについては perldebug を参照して下さい。
1 行のプログラムを指定するのに使用します。 -e が指定されると Perl は引数のリストからはファイル名を探しません。 複数の -e コマンドで、複数行のスクリプトを構成することができます。 通常のプログラムでセミコロンを置くところには、セミコロンを使うことに 気を付けてください。
-e と同様に振る舞いますが、暗黙に全てのオプション機能を(main コンパイル単位で)有効にします。 feature を参照してください。
起動時の $Config{sitelib}/sitecustomize.pl の実行を無効化します。
Perl は実行時に (BEGIN ブロックの中で) デフォルトで $Config{sitelib}/sitecustomize.pl を実行しようとさせるように ビルドできます。 これはシステム管理者が、perl がどのように振る舞うかをカスタマイズするための フックです。 例えば、perl が非標準の位置にあるモジュールを見つけられるように @INC 配列に エントリを追加するために使えます。
Perl は実際には以下のコードを挿入します:
BEGIN {
do { local $!; -f "$Config{sitelib}/sitecustomize.pl"; }
&& do "$Config{sitelib}/sitecustomize.pl";
}
実際には (require
ではなく) do
なので、sitecustomize.pl は 真の値を返す必要はありません。 このコードは main
パッケージで、独自のレキシカルスコープで動作します。 しかし、スクリプトが die すると、$@
は設定されません。
$Config{sitelib}
の値は C コードで決定され、Config.pm
は 読み込まれないので、ここの値は使われません。
コードは とても 早くに実行されます。 例えば、@INC
への変更は `perl -V` の出力に表示されます。 もちろん、END
ブロックは同様にとても遅くに実行されます。
この機能がコンパイルされているかどうかを実行時に決定するために、 $Config{usesitecustomize}
の値をチェックできます。
-a も有効なときに、split を行なう正規表現を指定します。 パターンは //
, ""
, ''
で囲むか、シングルクォートの中に書きます。 パターン中にリテラルな空白は使えません。
オプションの一覧を表示します。
<>
の構文で処理されたファイルを置き換えるための拡張子を 指定します。 これは、入力ファイルをリネームし、元の名前で出力ファイルを open し、 print() 文のデフォルトとしてその出力ファイルを select することで行ないます。 extension が指定されると、昔の内容のバックアップを行なう ファイル名の拡張子として、元のファイル名に付け加えられます。
extension が指定されないと、バックアップを作らず、現在のファイルが 上書きされます。
extension に *
が含まれていない場合、現在のファイル名の末尾に 接尾子として付け加えられます。 extension に一つ以上の *
の文字がある場合、 それぞれの *
は現在のファイル名で置き換えられます。 Perl 的に書くと、以下のようになります:
($backup = $extension) =~ s/\*/$file_name/g;
以下のようにすると、(接尾子の代わりに、あるいは接尾子に加えて) バックアップファイルに接頭子をつけることができます。
$ perl -pi'orig_*' -e 's/bar/baz/' fileA # backup to 'orig_fileA'
元のファイルのバックアップコピーを(既にある)他のディレクトリに作ることも できます:
$ perl -pi'old/*.orig' -e 's/bar/baz/' fileA # backup to 'old/fileA.orig'
以下の一行スクリプトは全て等価です:
$ perl -pi -e 's/bar/baz/' fileA # overwrite current file
$ perl -pi'*' -e 's/bar/baz/' fileA # overwrite current file
$ perl -pi'.orig' -e 's/bar/baz/' fileA # backup to 'fileA.orig'
$ perl -pi'*.orig' -e 's/bar/baz/' fileA # backup to 'fileA.orig'
シェルから以下のように起動すると:
$ perl -p -i.orig -e "s/foo/bar/; ... "
プログラムで以下のようにするのと同じで:
#!/usr/bin/perl -pi.orig
s/foo/bar/;
以下とほぼ等価です:
#!/usr/bin/perl
$extension = '.orig';
LINE: while (<>) {
if ($ARGV ne $oldargv) {
if ($extension !~ /\*/) {
$backup = $ARGV . $extension;
}
else {
($backup = $extension) =~ s/\*/$ARGV/g;
}
rename($ARGV, $backup);
open(ARGVOUT, ">$ARGV");
select(ARGVOUT);
$oldargv = $ARGV;
}
s/foo/bar/;
}
continue {
print; # this prints to original filename
}
select(STDOUT);
違うのは、-i の形式が、いつファイル名が変わったかを知るために、 $ARGV と $oldargv を比較する必要がないことです。 しかしながら、選択するファイルハンドルとして ARGVOUT は使用します。 ループのあとは、STDOUT がデフォルトのファイルハンドルとして再設定されます。
上述の通り、Perl はバックアップファイルを実際に出力が変更されたかどうかに 関わらず作成します。 従って、以下はファイルをコピーする変わった方法となります:
$ perl -p -i'/some/file/path/*' -e 1 file1 file2 file3...
or
$ perl -p -i'.orig' -e 1 file1 file2 file3...
個々のファイルの終わりに何かを付け加えたいときや、行番号を リセットしたいような場合に、個々の入力ファイルの終わりを知るために、 括弧の無い eof
を使うことができます。 ("eof" in perlfunc の例を参照してください。)
与えられたファイルに対して、Perl が指定された拡張子でバックアップファイルを 作れない場合、そのファイルはスキップされて(もしあれば)次のファイルに 移って継続します。
ファイルのパーミッションと -i に関する議論については、 "Why does Perl let me delete read-only files? Why does -i clobber protected files? Isn't this a bug in Perl?" in perlfaq5 を 参照して下さい。
-i は、ディレクトリを作ったり、ファイルの拡張子を取り除いたりは できません。
Perl は ~
を展開しません。 これはバックアップファイルを以下のようにして作る人々のためにはよいことです。
$ perl -pi~ -e 's/foo/bar/' file1 file2 file3...
-i は同じ名前で新しいファイルを作る前に元のファイルをリネームまたは 削除するので、Unix 形式のソフトリンクやハードリンクは保存されないことに 注意してください。
最後に、-i スイッチは、コマンドラインでファイルが指定されなくても 実行を妨げません。 この場合、バックアップファイルは作成されず(もちろん、元のファイルが 決定できません)、予想通り、STDIN から STDOUT に処理が行われます。
-I で指定されたディレクトリはモジュールの検索パス(@INC
)に 加えられます。
自動の行末処理を行なうようにします。 これには、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'
これはまず、$\
に改行 ($/
のデフォルト値) を設定し、 それから $/
にヌル文字を設定します。
-mmodule はプログラムの実行前に use
module ();
を 実行します。
-Mmodule はプログラムの実行前に use
module ;
を実行します。 モジュール名の後ろに追加のコードを加えるためにクォートを使うこともできます。 つまり '-Mmodule qw(foo bar)'
などです。
-M または -m の後の最初の文字がダッシュ(-
)の場合、 'use' の代わりに 'no' が使われます。
小さい組み込みのシンタックスシュガーとして、 '-Mmodule qw(foo bar)'
の 代わりに -mmodule=foo,bar または -Mmodule=foo,bar と 書くことができます。 これで、インポートするシンボルにクォートを使わなくてもよいようになります。 -Mmodule=foo,bar で生成される実際のコードは use module split(/,/,q{foo,bar})
です。 =
の形は -m と -M の間の違いを取り除くことに注意してください。
この結果、(例えば Foo が Exporter を継承していたりして、 Foo::import()
自身がバージョンチェックを行うように設定されていない限り) -MFoo=number は決してバージョンチェックは行いません。
以下のようなループが、実際のプログラムの回りにあるかのように Perl に 指示します。 sed -n や awk のようにファイル名引数上で繰り返しを 行なうことになります:
LINE:
while (<>) {
... # your program goes here
}
デフォルトでは、各行が印字されることはありません。 各行の印字を行なうには -p を参照してください。 引数で指定されたファイルがなんらかの理由でオープンできなかった場合、 Perl は警告を出して次のファイルに移ります。
また、<>
はコマンドライン引数を "open" in perlfunc に渡し、これは ファイル名として解釈する必要はないことに注意してください。 可能性のあるセキュリティの影響については perlop を参照してください。
以下にあげるのは、少なくとも 1 週間以上更新されていないファイルを効率的に 削除するものです:
find . -mtime +7 -print | perl -nle unlink
これは、ファイル名が見つかるごとにプロセスを起動しなくて済みますので、 find の -exec スイッチを使うよりも速くなります。 これはパス名に改行コードがあるとうまく扱えないバグの影響を受けますので、 -O の例に従うことで修正できます。
awk と同じように、暗黙に実行されるプログラムループの前後に実行される コードを指定するために、BEGIN
ブロックと END
ブロックを 使うことができます。
以下のようなループが、実際のプログラムの回りにあるかのように Perl に指示します。 sed のようにファイル名引数上で繰り返しを行なうことになります:
LINE:
while (<>) {
... # your program goes here
} continue {
print or die "-p destination: $!\n";
}
引数で指定されたファイルが何らかの理由でオープンできない場合、 Perl は警告を出し、次のファイルに移ります。 各行は、自動的に印字されることになります。 印字中のエラーは致命的とみなされます。 印字を抑制するには、-n スイッチを使ってください。 -p は -n スイッチを無効にします。
awk と同じように、暗黙に実行されるループの前後に実行されるコードを 指定するために、BEGIN
ブロックと END
ブロックを使うことができます。
コマンドライン上のプログラム名の後から、ファイル名引数 (または引数 --) の前までのスイッチのための、原始的な解析を 行なえるようにします。 ここで見つかったスイッチは、@ARGV から取り除かれ、対応する Perl プログラムの 変数に設定されます。 以下のプログラムは、-xyz というスイッチを付けて実行された時にだけ、 "1" と表示し、-xyz=abc と起動された時に "abc" と表示します。
#!/usr/bin/perl -s
if ($xyz) { print "$xyz\n" }
--help のようなスイッチは変数 ${-help} を作成するので、strict refs
を 満たさないことに注意してください。 また、警告を有効にしたスクリプトでこのオプションを使うと、大量の "used only once" という偽警告がでることになります。
Perl がプログラムを探すときに環境変数 PATH を参照するようにします (プログラム名がディレクトリセパレータを含むときを除きます)。
プラットフォームによっては、Perl はファイルを探すときに拡張子を 追加します。 例えば Win32 プラットフォームでは、元々のファイル名で検索が失敗した場合、 ".bat" と ".cmd" の拡張子が追加されます。 但し既にそのような拡張子がついていない場合だけです。 Perl が DEBUGGING を有効にしてコンパイルされていた場合、-Dp スイッチを 使うことでどのように検索が行われているかを表示させることができます。
これは、#! をサポートしていないプラットフォームで、#! による実行を エミュレートするために使います。 また、#! を使ったスクリプトで、通常はシェルの $PATH 検索メカニズムで 見つけられるようなスクリプトをデバッグするのにも便利です。
この例は Bourne shell 互換のシェルを持つ多くのプラットフォームで動きます:
#!/usr/bin/perl
eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}'
if $running_under_some_shell;
システムは、最初の行を無視し、プログラムを /bin/sh に渡し、 /bin/sh は Perl プログラムをシェルプログラムとして実行しようとします。 シェルは 2 行目を通常のシェルコマンドとして実行し、Perl インタプリタを 起動することになります。 $0 にフルパス名が入っているとは限らないシステムもありますので、 -S が Perl に必要に応じてプログラムを探すように指示します。 Perl がプログラムを見つけると、これらの行の解析を始めますが、 $running_under_some_shell が真になることがないため、 無視することになります。 プログラムが csh で解釈される場合には、たとえファイル名内に埋め込まれた スペースなどを扱うことができなくても ${1+"$@"}
を $*
で 置き換える必要があるかもしれません。 csh ではなく、sh を起動するように、いくつかのシステムでは、#! の行を Perl も無視することになっている、コロンだけの行で置き換える必要が あるかもしれません。 そういった制御が効かないシステムでは、csh でも sh でも Perl でも使える、回りくどい方法を使うことが必要です:
eval '(exit $?0)' && eval 'exec perl -wS $0 ${1+"$@"}'
& eval 'exec /usr/bin/perl -wS $0 $argv:q'
if $running_under_some_shell;
ファイル名にディレクトリセパレータが含まれていた場合 (つまり絶対パスまたは相対パスだった場合)、そしてそのファイルが なかった場合、ファイル拡張子を追加するプラットフォームでは ひとつずつ拡張子を追加して、ファイルを探します。
DOS 風のプラットフォームでは、プログラムにディレクトリセパレータが 含まれていなかった場合、PATH を探す前に最初にカレントディレクトリを 探します。 Unix プラットフォームでは、プログラムは厳密に PATH からのみ探されます。
-T と同様ですが、汚染チェックは致命的エラーではなく警告を発生させます。 この警告は通常通り no warnings qw(taint)
で制御できます。
注意: これは -T の代用品ではありません。 これは昔のコードを安全にするのを助けるために一時的に使用されるためだけの ものです: 本当の製品版コードと最初から書く安全なコードのためには常に本当の -T を使ってください。
「汚染」チェックをオンにして、テストできるようにします。 通常、このチェックは setuid や setgid のスクリプトを実行するときにだけ、 行なわれます。 CGI プログラムやインターネットサーバーを Perl で書くときのように、 信用できるとは限らない人が動かすようなプログラムではこれを明示的に 有効にするのはいい考えです。 詳細については perlsec を参照してください。 セキュリティ上の理由から、このオプションは Perl にかなり早く 渡さなければなりません。 これは通常コマンドラインの最初の方につけるか、#! 構造に対応する システムではここに書くかです。
この古いスイッチはプログラムのコンパイル後、コアダンプを 行なうようにします。 理論的には、このコアダンプを持ってきて(Perl の配布では提供されていませんが) undump プログラムを使って、実行ファイルに変換することができます。 これは多少ディスク容量を食いますが (実行ファイルを sprit することで 少しは減ります)、実行開始を速くすることができます。 (減らしても、"hello world" の実行ファイルは、私のマシンで 200K 程に なります。) ダンプする前に部分的にプログラムを実行しておきたい場合には、 このスイッチの代わりに dump() 演算子を使ってください。 注意:undump が実行できるのは特定の環境下ですし、 これが使えない移植バージョンの Perl もあるでしょう。
Perl に安全でない操作を許可します。 現在のところ、「安全でない」操作には、スーパーユーザとして実行中に ディレクトリを削除しようとすることと、致命的な汚染チェックを警告に替えて、 setuid プログラムを実行することです。 -w スイッチ(あるいは $^W
変数)は汚染チェックの警告が実際に 生成される ためにこのオプションと共に使われなければなりません。
Perl 実行ファイルのバージョンとパッチレベルを表示します。
Perl の主な設定値と @INC の現在の値を表示します。
指定された設定変数の値を STDOUT に表示します; configvar 引数が正規表現のように見えるもの(英字以外を含んでいる)の場合は 複数表示します。 例えば:
$ perl -V:libc
libc='/lib/libc-2.2.4.so';
$ perl -V:lib.
libs='-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc';
libc='/lib/libc-2.2.4.so';
$ perl -V:lib.*
libpth='/usr/local/lib /lib /usr/lib';
libs='-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc';
lib_ext='.a';
libc='/lib/libc-2.2.4.so';
libperl='libperl.a';
....
さらに、追加のコロンはフォーマットの制御に使います。 末尾のコロンは改行と終端子 ';' を抑制し、シェルコマンド中にクエリを 組み込めるようにします。 (記憶法: PATH セパレータ ':'。)
$ echo "compression-vars: " `perl -V:z.*: ` " are here !"
compression-vars: zcat='' zip='zip' are here !
先頭のコロンはレスポンスの 'name=' の部分を削除し、必要な名前に マッピングできるようにします。 (記憶法: 空ラベル)
$ echo "goodvfork="`./perl -Ilib -V::usevfork`
goodvfork=false;
もし位置パラメータの値を名前なしで必要なら、先頭のコロンと末尾のコロンを 両方使えます。 以下の場合、PERL_API パラメータはアルファベット順に返されることに 注意してください。
$ echo building_on `perl -V::osname: -V::PERL_API_.*:` now
building_on 'linux' '5' '1' '9' now
1 度しか使われない変数名、設定される前に使われている変数、サブルーチンの 再定義、未定義のファイルハンドルの参照や、読み込み専用でオープンした ファイルハンドルへの書き込み、数値に見えない値を数値として使った場合、 配列をスカラであるかのように使った場合、100 段階以上のサブルーティンの再帰、 その他たくさんの疑わしい事に警告を出します。
このスイッチは実際には内部の $^W
変数を有効にするだけです。 __WARN__
フックを使って特定の警告を無効にしたり致命的エラーに したりできます。 これについては perlvar と "warn" in perlfunc を参照して下さい。 perldiag と perltrap も参照して下さい。 もし警告のクラス全体を操作したいなら、新しく粒度の細かい 警告機能もあります。 warnings や perllexwarn を参照して下さい。
no warnings
や $^W
の設定に関わらず全ての警告を有効にします。 perllexwarn を参照して下さい。
use warnings
や $^W
の設定に関わらず全ての警告を無効にします。 perllexwarn を参照して下さい。
メールのような大きな無関係のASCII テキストのかたまりの中にプログラムが 埋め込まれている事を Perl に伝えます。 最初の #! で始まり、"perl" という文字列を含む行までの、先行するゴミは 捨てられます。 その行にある意味を持つスイッチは適用されます。
プログラムによる行番号への全ての参照 (警告、エラー…) は #! 行を 最初の行として扱います。 従って、プログラムの 2 番目の行 (ファイルとしては 100 行目) での警告は 100 行目ではなく 2 行目として報告されます。 これは #line 指示子を使って上書きできます。 ("Plain-Old-Comments-(Not!)" in perlsyn を参照してください。)
directory が指定されると、Perl はプログラムの実行前に、そのディレクトリに 移ります。 -x
スイッチは先行するゴミの処分を制御するだけです。 プログラムの後に無視すべきゴミがある場合には、__END__
でプログラムを 終了する必要があります (その、後に続くゴミの一部または全部は、必要に応じて DATA ファイルハンドルを通して、そのプログラムで処理する事ができます)。
ディレクトリが指定される場合は、これは -x の直後、空白なしに 引き続かなければなりません。
chdir の引数がないときに使われます。
chdir の引数がなく、HOME がセットされていないときに使われます。
サブプロセスを実行するときと、-S が指定されたときにプログラムを 探すのに使われます。
Perl のライブラリファイルを探すときに標準ライブラリディレクトリと カレントディレクトリを探す前に探すディレクトリのリストです。 特定の場所におけるアーキテクチャ依存のディレクトリは、もしあれば自動的に 追加されます(この検索はインタプリタ起動時に行われます)。
PERL5LIB が定義されていなければ、PERLLIB が使われます。 ディレクトリは(PATH と同様に)Unix 風のプラットフォームではコロンで区切られ、 Windows ではセミコロンで区切られます(適切なパス区切り文字は perl -V:path_sep
コマンドでわかります)。
(プログラムが setuid または setgid で実行されているか、-T か -t の スイッチが指定されて)汚染チェック付きで動作している場合、どちらの環境変数も 使われません。 代わりにプログラム中で以下のようにするべきです:
use lib "/my/directory";
コマンドラインオプション(スイッチ)です。 この変数のスイッチは全ての Perl コマンドラインで指定されたかのように 扱われます。 -[CDIMUdmtwW] オプションのみが有効です。 (プログラムが setuid または setgid で実行されているか、-T スイッチが 指定されて)汚染チェック付きで動作している場合、この変数は無視されます。 PERL5OPT が -T で始まっている場合、汚染チェックが有効となり、残りの オプションは無視されます。
空白(またはコロン)で区切られた PerlIO 層のリストです。 perl が IO に PerlIO システムを使うようにコンパイルされている場合 (これがデフォルトです)、これらの層が perl の IO に影響を与えます。
変数"属性"との類似性を強調するために層名を :perlio
のようにコロンで 始める慣習があります。 しかしプログラムは層を定義する文字列のパースする (PERLIO 環境変数のデコードにも使われます)ときにコロンをセパレータとして 扱います。
PERLIO をセットしない、または空文字列をセットすると、プラットフォームの デフォルトの層の組み合わせと等価です; 例えば、Unix 風のシステムでは :unix:perlio
で、Windows やその他の DOS 風のシステムは :unix:crlf
です。
このリストは 全ての perl の IO のデフォルトとなります。 従って組み込みの層のみがこのリストに記述可能です。 なぜなら(:encoding() のような)外部読み込みの層はロードするために IO が必要だからです。 デフォルトとして外部エンコーディングを追加する方法については "open pragma" を参照してください。
PERLIO 環境変数に加えることが妥当な層の簡単な一覧を以下に示します。 詳細については PerlIO を参照してください。
以下に示す :utf8
フラグを 無効にする ための擬似層です。 グローバルな PERLIO 環境変数にこれを含めるのが有用な場合は ありそうもないです。 おそらく :crlf:bytes
か :perlio:bytes
のことを考えているのでしょう。
"テキスト"と"バイナリ"ファイルを識別する CRLF から "\n" への変換を MS-DOS 及び似たようなオペレーティングシステムの方式で行う層です。 (現在のところ Control-Z をファイルの終わりと見なすところまで MS-DOS を まねてはいません。)
ファイルの"読み込み"に mmap()
を使ってファイル(全体)をプロセスの アドレス空間に割り当て、それを PerlIO の"バッファ"として使うための層です。
これは"stdio風"のバッファリングを PerlIO "層" として再実装したものです。 従ってどのような層からも操作時に呼び出されます(典型的には :unix
)。
先頭の層を除去するための実験的な擬似層です。 ニトログリセリンに対するのと同様の慎重さを持って使ってください。
他の層を操作するための擬似層です。 :raw
層を適用することは binmode($fh)
を呼び出すのと等価です。 これはストリームの各バイトを何の変換もなしに通過させます。 特に CRLF 変換やロケールからの :utf8 が無効になります。
昔のバージョンの Perl と異なり、:raw
は :crlf
の逆 ではありません - ストリームのバイナリの性質に影響を与える その他の層も除去されるか無効になります。
この層はシステムの ANSI C "stdio" ライブラリコールをラップした PerlIO インターフェースを提供します。 この層はバッファリングと IO の両方を提供します。 :stdio
層は CRLF 変換を 行わない ことに注意してください。 たとえそれがプラットフォームの通常の振る舞いであっても、です。 これを行うためには :crlf
層が必要です。
read
, write
, lseek
などを呼び出す低レベル層です。
出力が utf8 で、入力は既に妥当な utf8 の形になっていると下位の層に伝える フラグをオンにする擬似層です。 妥当性についてはチェックされないので、入力については注意して扱うべきです。 一般的に、UTF-8 でエンコードされたデータを読むときには :encoding(utf8)
が 最善の選択肢です。
Win32 プラットフォームにおいて、この 実験的 層は unix 風の数値の ファイル記述子層の代わりにネイティブな "ハンドル" IO を使用します。 このリリースではバグっぽいことがわかっています。
全てのプラットフォームでデフォルトの層の組み合わせは納得できる結果に なっているはずです。
Unix プラットフォームではこれは "unix perlio" または "stdio" と等価です。 configure スクリプトはシステムのライブラリがバッファへの高速アクセス方法を 提供する場合は"stdio"実装を使うよう設定し、そうでなければ"unix perlio" 実装を使います。
Win32 ではデフォルトは"unix crlf"です。 Win32 の"stdio" は perl IO にとって、C コンパイラのベンダー/バージョン依存の 大量のバグ/仕様漏れがあります。 バッファとして自身の crlf
層を使うことでこれらの問題を回避し、 物事をより一貫したものにします。 crlf
層はバッファリング時に CRLF と "\n" の変換を行います。
このリリースでは Win32 での基底層として unix
を使うことで、未だに C コンパイラの数値のファイル記述子ルーチンを使います。 拡張を予定されている実験的なネイティブの win32
層があり、最終的には これが Win32 でのデフォルトとなる予定です。
PERLIO 環境変数は、perl が汚染モードで実行されるときには完全に無視されます。
ファイルまたはデバイスの名前をセットすると、PerlIO サブシステムのいくつかの 操作がそのファイルに(追記モードで)記録されます。 Unix での典型的な使い方は以下の通りです:
PERLIO_DEBUG=/dev/tty perl script ...
Win32 では以下がほぼ等価です:
set PERLIO_DEBUG=CON
perl script ...
この機能は、setuid されたスクリプトや -T で実行されているスクリプトでは 無効になります。
Perl ライブラリを探すのに標準ライブラリとカレントディレクトリの前に 検索するディレクトリのリストです。 PERL5LIB が定義されていると、PERLLIB は使われません。
PERLLIB 環境変数は、perl が汚染モードで実行されるときには完全に 無視されます。
デバッガコードを読み込むのに使われるコマンドです。 デフォルトは以下の通り:
BEGIN { require 'perl5db.pl' }
PERL5DB 環境変数は perl が裸の -d スイッチで開始されたときにのみ 使われます。
真の値にセットされると、デバッグするコードがスレッドを使うことをデバッガに 示します。
"バッククォート" コマンドや system() を実行するために Perl が内部的に 使わなければならない代替シェルを指定します。 デフォルトは WindowsNT では cmd.exe /x/d/c
、Windows95 では command.com /c
です。 値はスペース区切りと考えられます。 (空白やバックスラッシュのような) 保護する必要がある文字の前には バックスラッシュがつけられます。
COMSPEC の値はユーザーによってかなり様々で、移植性の問題を引き起こすので、 Perl はこの目的に COMSPEC は使わないことに注意してください。 さらに、Perl は対話的な用途には向かないシェルも利用できますが、 COMSPEC にそのようなシェルを指定すると他のプログラム (普通は対話的な用途に適したシェルを探すのに COMSPEC を使います)の適切な 利用を邪魔するかもしれません。
Perl 5.10.0 と 5.8.8 以前では、PERL5SHELL は外部コマンドを実行するときに 汚染チェックされませんでした。 Windows 上で汚染モードで実行するときには、明示的に $ENV{PERL5SHELL}
を 設定(または削除)することを勧めます。
1 にセットすると、IFS 非互換の LSP を使えるようにします。 Perl は普通 IFS 互換の LSP を探します; Windows のソケットを本当の ファイルハンドルとしてエミュレートするために必要だからです。 しかし、これは全てのアプリケーションが IFS 非互換の自身の LSP を使うことを 求める McAfee Guardian のようなファイアウォールでは問題が起きます; 明らかに、Perl は普通そのような LSP を使うことを避けるからです。 この環境変数を 1 にセットすることで、 Perl は単にカタログに挙げられている もののうち最初の適切な LSP を使用し、これにより McAfee Guardian は 幸せなままです (そしてこの特定の場合においては、McAfee Guardian の LSP は 実際には動作するために IFS 互換である必要があるアプリケーションのために 小細工をしているので、 Perl も正しく動きます)。
Perl が Perl 配布パッケージに含まれる malloc ルーチンを使って コンパイルされている場合(perl -V:d_mymalloc
が 'define' の場合)にのみ 有効です。 設定されると、実行後にメモリ状況が表示されます。 1 を超える数値が設定されると、コンパイル後にもメモリ状況を表示します。
Perl の実行ファイルが -DDEBUGGING 付きで構築された場合にのみ有効です。 このオプションはオブジェクトやその他のリファレンスのグローバルな デストラクタの振る舞いを制御します。 さらなる情報については "PERL_DESTRUCT_LEVEL" in perlhack を参照してください。
1 にセットすると、 Perl は 全ての 未定義シンボルをダイナミック ライブラリをロードしたときに解決します。 デフォルトの振る舞いは使われるときにシンボルを解決します。 この変数を設定することで、拡張機能のテスト時にたとえテストスイートが 呼び出さなくても関数名のスペルミスによるエラーを確実に受け取ることが できるので便利です。
encoding
プラグマを明示的なエンコーディング名を指定せずに使用した場合、 PERL_ENCODING 環境変数がエンコーディング名として使われます。
(Perl 5.8.1 から) perl の内部ハッシュ関数のランダム化に使われます。 5.8.1 以前の振る舞いをエミュレートするためには、整数を指定します (ゼロは 5.8.0 と完全に同じ順序を意味します)。 "5.8.1 以前" というのは、その他のことも含めて、Perl を何度実行しても ハッシュキーの並び順が常に同じであることを意味します。
Perl 5.8.0 ではデフォルトではほとんどのハッシュは同じ順序で要素を返します。 ハッシュからハッシュの単位で、ハッシュキー挿入中に異常なデータが検出されると、 ハッシュは代替のランダムハッシュの種に切り替えます。
デフォルトの振る舞いは、PERL_HASH_SEED がセットされない限り ランダム化されます。 perl が -DUSE_HASH_SEED_EXPLICIT
付きでコンパイルされた場合、 デフォルトの振る舞いは PERL_HASH_SEED がセットされない限り ランダム化 されません。
PERL_HASH_SEED がセットされないか、数値でない文字列がセットされた場合、 Perl はオペレーティングシステムとライブラリが提供する擬似乱数の 種を使用します。
ハッシュの種は微妙な問題であることに注意してください。 ハッシュは Perl コードに対するローカル・リモート攻撃から守るために ランダム化されます。 手動で種を設定することによりこの守りは部分的に、あるいは完全に失われます。
さらなる情報については "Algorithmic Complexity Attacks" in perlsec と "PERL_HASH_SEED_DEBUG" を参照してください。
(Perl 5.8.1 から) これを 1 に設定すると、実行開始時にハッシュの種の 値を画面(STDERR)に出力します。 これは "PERL_HASH_SEED" と組み合わせることでハッシュのランダム化に よる非決定的な振る舞いのデバッグを助けることを目的としています。
ハッシュの種は微妙な問題であることに注意してください: これを知ることで、リモートからでも Perl のコードに対してサービス拒否攻撃を 仕掛けることが出来ます。 さらなる情報については "Algorithmic Complexity Attacks" in perlsec を 参照してください。 知る必要のない人々に対して ハッシュの種を公開しないでください。 Hash::Util の hash_seed() も参照してください。
perl が -Accflags=-DPERL_MEM_LOG
で設定されていると、環境変数 PERL_MEMLOG
を設定することでデバッグメッセージのログ出力を有効にします。 値は <number>[m][s][t]
の形式で、number
は書き込みたい ファイル記述子番号、文字の組み合わせはメモリ (m) と SV(s) で、 オプションとしてタイプスタンプ (t) です。 例えば、PERL_MEMLOG=1mst
は全てのログ情報を標準出力に出力します。 応用として、開いている他のファイル記述子に書き込むこともできます;
bash$ 3>foo3 PERL_MEM_LOG=3m perl ...
Perl と VMS 専用の @INC のための論理デバイスを含む、 変換が隠されたルートとなる論理名です。 VMS の Perl に影響を与えるその他の論理名としては PERLSHR, PERL_ENV_TABLES, SYS$TIMEZONE_DIFFERENTIAL がありますが、これらはオプションです。 詳細については Perl ソース配布パッケージの perlvms と README.vms で 議論されています。
Perl 5.8.1 以降で有効です。 これに unsafe
をセットすると、Perl 5.8.0 以前のシグナルの振る舞い (直接的ですが安全ではありません)が復元されます。 safe
をセットすると安全な(遅延する)シグナルが使われます。 "Deferred Signals (Safe Signals)" in perlipc を参照してください。
-C コマンドラインスイッチと等価です。 これは真偽値変数ではないことに注意してください。 これを "1"
にセットすることは(どんな意味においても)「Unicode を 有効にする」ための正しい方法ではありません。 しかし、「Unicode を無効にする」ために "0"
をセットすることは出来ます (あるいは Perl の起動前にあなたのお使いのシェルで PERL_UNICODE を 未設定にすることでも出来ます)。 さらなる情報については -C
スイッチの説明を参照してください。
chdir の引数がなく、HOME と LOGDIR がセットされていないときに使われます。
特定の自然言語に特有のデータを Perl がどのように扱うかを制御する 環境変数もあります。 perllocale を参照して下さい。
これらの他には、実行されているプログラムあるいは子プロセスがが有効に しない限り、Perl は環境変数を使いません。 しかし、setuid で動作するプログラムは何かをする前に、単に人々に変な気を 起こさせないために以下のコードを入れておくのがよいです。
$ENV{PATH} = '/bin:/usr/bin'; # or whatever you need
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};