とほほのperl入門(リファレンス編)

目次

プログラム制御

if (expr) { statements }

expr が真であれば statements を実行します。

if ($num > 5) {
    print "num is greater than 5.\n";
}

else

if と組み合わせて「さもなくば」の処理を行います。

if ($num == 5) {
    print "num is 5.\n";
} else {
    print "num is not 5.\n";
}

elsif

else if の意味で、if と組み合わせて「あるいは、もし」の処理を行います。

if ($num == 5) {
    print "num is 5.\n";
} elsif ($num == 6) {
    print "num is 6.\n";
} elsif ($num == 7) {
    print "num is 7.\n";
} else {
    print "num is not 5, 6, or 7.\n";
}

unless

if と逆の意味で、「もし・・・でなければ」の処理を行います。

unless ($num == 5) {
    print "num is not 5.\n";
}

for (expr1; expr2; expr3) { statements }

まず expr1 を実行し、その後、expr3 を行いながら expr2 が真の間 statements を実行します。

for ($i = 1; $i <= 10; $i++) {
    print "i = $i\n";
}

for var (from .. to) { statement }

from から to の数分ループします。var を省略すると $_ に格納されます。

for my $num (1..10) {
    print "$num\n";
}
for (1..10) {
    print "$_\n";
}

for var (array) { statement }

foreach var (array) { statements }

配列の各要素に対して処理を行います。forforeach は同義ですが、リスト操作の際は foreach を使用するのが一般的です。

@nums = (11, 22, 33, 44, 55);
foreach my $num (@nums) {
    print "num = $num\n";
}

$num を省略した場合は、省略時変数 $_ が用いられます。

foreach (@nums) {
    print "num = $_\n";
}

while (expr) { statements }

expr が真の間、statements を繰り返します。

$num = 1;
while ($num < 10) {
    print "num = $num\n";
    $num++;
}

do { statements }
          do expr

statementssubroutine を実行します。次の例では最後の式の値が do の戻り値となります。

$xx = do { $yy = 5; $zz = 8; };
print "$xx\n";                           # 8

次の例では mylib.pl という外部ファイルを perl のライブラリとして呼び出します。(ただし、require "mylib.pl"; を用いるのが一般的。)

do "mylib.pl";

do を用いて、ifunlesswhileuntil 文の順序を変更することができます。

$num = 5;
do {
    print "num is 5.\n";
} if ($num == 5);
do {
    print "num = $num\n";
    $num++;
} while ($num < 10);

until (expr) { statements }

while の逆で、expr が真になるまで、statements を繰り返します。

$num = 10;
until ($num == 0) {
    print "num = $num\n";
    $num--;
}

next label

label で指定したループ、省略時は最も内側のループの次の繰り返しを実行します。

for (my $i = 0; $i < 10; $i++) {
    if ($i == 5) { next; }
    print "i = $i\n";
}

loop1:
for (my $i = 0; $i < 10; $i++) {
    for (my $j = 0; $j < 3; $j++) {
        if ($i == 5) { next loop1; }
        print "i, j = $i, $j\n";
    }
}

last label

label で指定したループ、省略時は最も内側のループを抜けます。

for (my $i = 0; $i < 10; $i++) {
    if ($i == 5) { last; }
    print "i = $i\n";
}

loop1:
for (my $i = 0; $i < 10; $i++) {
    for (my $j = 0; $j < 3; $j++) {
        if ($i == 5) { last loop1; }
        print "i, j = $i, $j\n";
    }
}

redo LABEL

label で指定したループ、省略時は最も内側のループの現在のループを繰り返しを実行します。

while (1) {
    print "Input number: ";
    $in = <STDIN>;
    chomp($in);
    if ($in !~ /^\d+$/) {
        print "$in is not a number.\n";
        redo;
    }
    print "$in\n";
}

goto label

label の場所にジャンプします。label はラベル名にコロン(:)をつけて宣言し、コロン無しのラベル名を指定してジャンプします。

sub myFunc1 {
    $err = doSomething1();
    if ($err) { goto done; }
    $err = doSomething2();
    if ($err) { goto done; }

done:
    return $err;
}

sleep(expr)

expr 秒間処理を中断して待ちます。

print "Foo\n";
sleep(3);
print "Baa\n";

expr を省略すると SIGALRM が発生するまで待ち、実際にまった秒数を返します。

sub sigalarm { print "ALARM!\n"; }
$SIG{'ALRM'} = "sigalarm";
alarm(3);

print "Foo\n";
sleep();
print "Baa\n";

eval(string)
          eval { ... }

string { ... } を perl のスクリプトとみなして実行します。string の場合は毎回コンパイルします。{ ... } の場合は最初のみコンパイルするので高速です。最後に実行した命令の結果が戻り値として返されます。perl がエラーメッセージを出して終了するような命令や、die が実行された場合、undef を返し、$@にエラーメッセージを格納します。dbmopen, symlink, flock など、実装されているかどうか分からない命令や、0除算の可能性のある割り算を行う際に、eval を用いて perl が異常終了するのを防ぐ事ができます。(eval { ... }; のセミコロン(;)に注意)

print eval("3 * (5 + 3)") . "\n";

$x = 10; $y = 0;
$ans = eval { $x / $y; };
if ($@) { warn "WARNING: $@"; }

open(OUT, "> xx");
eval { flock(OUT, 2); };
if ($@) { warn "WARNING: flock isn't supported.\n"; }

exec(list)

list で指定した外部コマンドに処理を移します。system() と異なり、exec() を呼び出した以降のスクリプトは実行されません。

print "Foo\n";
$| = 1;
exec("/bin/ls", "-l");
print "Baa\n";                     # この行は実行されない

exit(expr)

perl スクリプトを終了します。終了コードとして expr の値を返します。通常、成功終了は 0、異常終了は 0 以外の値を返します。expr 省略時は 0 を返します。

print "Foo\n";
exit(0);
print "Baa\n";                    # この行は実行されない

die(list)

perl スクリプトを終了します。listSTDERR に出力し、$! の値(もし $!0 なら($?>>8) の値)を perl スクリプトの戻り値とします。eval の中で使用した場合はスクリプトを終了せず、list$@ に設定し、evalundef で終了します。list の末尾に改行が無い場合は、スクリプト名や行番号などが末尾に付加されます。

open(IN, $file) || die "Can't open file.\n";

warn(list)

die と同様のメッセージを標準エラー出力 STDERR に出力します。ただしプロセスは終了しません。

open(IN, $file) || warn "Can't open file.\n";

dump label

直ちにコアダンプしてスクリプトを終了します。ラベルを使用した場合は、undump コマンドでコアファイルから実行ファイルを生成して再実行すると、label の場所から実行されます。Perl 5.18.0 以降は CORE::dump() と記述する必要があります。ただしこの機能は現在では非推奨(実質的に廃止機能)となっています。

    CORE::dump label1;
label1:

サブルーチン・パッケージ・ライブラリ

sub funcname { ... }

サブルーチンを定義します。詳細は サブルーチン を参照。

sub add {
    return $_[0] + $_[1];
}
print add(5, 6);

return list

サブルーチンを終了します。list をサブルーチンの戻り値とします。return 文を省略すると、最も最後の式の値が戻り値となります。

sub add {
    return $_[0] + $_[1];
}

caller(expr)
        caller()

サブルーチンを呼び出した側のパッケージ名、ファイル名、行番号を得ます。

sub func {
    ($package, $filename, $line) = caller;
    print "$package, $filename, $line\n";
}

func()

prototype(func)

指定した関数のプロトタイプ情報を取得します。

sub func($$) { ... }
print prototype("func") . "\n";      # $$

wantarray()

サブルーチンの中で使用し、サブルーチンの戻り値が配列を期待しているかどうかを調べます。次の例は、@xx = func() で呼び出すと (1, 2, 3) を返し、$xx = func() で呼び出すと "ABC" を返します。

sub func {
    return wantarray() ? (1, 2, 3) : "ABC";
}
@xx = func(); print "@xx\n";        # 1 2 3
$xx = func(); print "$xx\n";        # ABC

require expr
        require expr
        require

ライブラリファイルを読み込みます。ライブラリファイルは習慣的に *.pl の拡張子を持つ perl スクリプトです。expr を省略した場合は $_ をファイル名とみなします。

require "jcode.pl";

use module

モジュールや機能を読み込んだりバージョンを指定したりします。

use strict;
use feature 'class';
use v5.38;
use Socket;
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);

no module

use と逆にその機能を無効化します。

no warnings 'experimental::class';

package packagename

これ以降(ファイルの終わりか次の package が現れるまで)のスクリプトを packagename で示すパッケージとして扱うことを宣言します。パッケージの内部では独自の変数名やサブルーチン名を持てるので、パッケージの内部と外部でたまたま変数名などが重複することによる悲劇を防ぐことができます。パッケージ内の変数やサブルーチン名は「パッケージ名::変数名」で指定します。

calc.py
package calc;
sub add {
    return $_[0] + $_[1];
}
1;
test.py
require "./calc.py";
print calc::add(3, 5) . "\n";

ファイル入出力

open(filehandle, mode, file)
        open(filehandle, file)

ファイルやコマンドをオープンし、ファイルハンドルを得ます。成功すれば非 0 を、失敗すれば undef を返します。expr を省略した場合は、filehandle と同じ名前の変数の値が expr とみなされます。指定するファイル名には http://~ などの URL は指定できないので注意。

ファイルを読み込みモードでオープンします。

open(my $fh, "<", "example.txt");
while (<$fh>) { print; }
close($fh);

第二引数に ">" を指定すると書込みモードでオープンします。

open(my $fh, ">", "example.txt");
print $fh "Hello!\n";
close($fh);

第二引数に ">>" を指定すると追加書込みモードでオープンします。

open(my $fh, ">>", "example.txt");
print $fh "Hi!\n";
close($fh);

第二引数に "+>;" を指定すると読み書きモードでオープンします。ファイルが無ければ作成します。ファイルが存在していればオープン時にファイルを空にします。

open(my $fh, "+>", "example.txt");
print $fh "Hello!\n";      # "Hello!" を書き込む
seek($fh, 0, 0);           # ファイルポインタを先頭に戻す
$msg = <$fh>;              # 1行読み込む
print "$msg\n";
close($fh);

第二引数に "+<" を指定すると読み書きモードでオープンします。オープン時ファイルの内容はそのまま。

open(my $fh, "+<", "example.txt");
$line = <$fh>;             # 先頭の1行を読み込む
print "$line";
seek($fh, 0, 2);           # ファイルポインタを末尾に移動する
print $fh "Bye!\n";        # メッセージを追記する
close($fh);

下記の様にパイプ(|)を用いると外部コマンドを起動し、その結果を読み込みます。

open(my $fh, "cat example.txt | wc |");
while(<$fh>) { print; }
close($fh);

パイプを下記の位置に記述すると、外部コマンドを起動し、コマンドに出力を渡します。

open(my $fh, "| wc");
print $fh "ABC\n";
print $fh "DEF\n";
print $fh "HIJ\n";
close($fh);

$|1 を指定すると、書き込み時、バッファリングしないようにします。下記の例ではデフォルトファイルディスクリプタを $fh に変更し、$| = 1 でバッファリングを抑制し、デフォルトファイルディスクリプタを元の $old に戻しています。

open(my $fh, "> example.txt");
$old = select($fh); $| = 1; select($old);
print $fh "...\n";
   :

getc(filehandle)
       getc()

filehandle から 1文字読み込みます。filehandle 省略時は標準入力 STDIN から読み込みます。ファイルの終端に達すると undef を返します。

while (defined(my $c = getc($fh))) {
    print $c;
}

read(filehandle, scalar, length, offset)
        read(filehandle, scalar, length)

ファイルハンドルから length バイト分のデータを読み出して scalar に格納します。offset を指定すると読み出したデータを scalaroffset バイト目から格納します。成功時は読み出したバイト数を、ファイルの終端に達すると 0 を、失敗時は undef を返します。バイナリデータを読み出す際に便利ですが、MS-DOS や Windows などでは binmode() を使用しなくてはならない場合があります。テキストファイルを読み込むのであれば、read ではなく、<filehandle> の形式を用いるのが一般的です。

open(my $fh, "example.txt");
read($fh, $buf, -s "example.txt");   # ファイル内容を $buf にファイルサイズ(-s)分読み込む
close($fh);
print $buf;

readline(filehandle)

ファイルハンドルから1行分読み込みます。下記の2行は同じ動作になります。

$line = <STDIN>;
$line = readline(STDIN);

print(filehandle list)
        print(list)
        print filehandle list
        print list
        print

filehandlelist を書き出します。filehandle を省略すると STDOUT (select で変更可能) に書き出します。list を省略すると $_ を書き出します。行末には改行がつかない点が say と異なります。

print;                 # $_ を標準出力に書き出す
print "Hello!";        # Hello! を標準出力に書き出す
print $fh "Hello!";    # Hello! を $fh に書き出す

printf(filehandle format, list)
        printf(format, list)
        printf filehandle format, list
        printf format list

filehandlelist を書き出します。filehandle を省略すると STDOUT (select で変更可能) に書き出します。list を省略すると $_ を書き出します。format にはフォーマットを指定します。例えば、%s は文字列、%d は整数値、%f は小数に変換されます。%10s%10d はそれぞれ、10文字分の文字列、数値を表わす。%-10s%-10d は右揃えで表示します。「バックスラッシュ(\)+文字」は特殊文字として判断され、改行(\n)、タブ(\t)、復帰(\r)などと判断されます。

$name = "Yamada";
$age = 36;
printf("Name=%s, Age=%d\n", $name, $age);

say(filehandle list)
        say(filehandle)
        say(list)
        say

filehandlelist を書き出します。filehandle を省略すると STDOUT (select で変更可能) に書き出します。list を省略すると $_ を書き出します。行末には改行がつく点が print と異なります。使用するには use feature 'say' または use 5.10.0 が必要です。

use feature 'say';
say "Hello world!";

tell(filehandle)
        tell()

ファイルの現在の読み込み・書き込み位置を得ます。

$pos = tell($fh);

seek(filehandle, pos, whence)

ファイルの読み込み・書き込み位置を変更します。whence が 0 の時はファイルの先頭から pos バイト目に、whence が 1 の時は現在の位置から pos バイト移動した場所(負の数も指定可能)に、whence が 2 の時はファイルの終わりから pos バイト目に移動します(通常は負数を指定)。成功すれば 1、さもなくば 0 を返します。

seek($fh, 10, 0);       # ファイルの先頭から10バイト目
seek($fh, 10, 1);       # 現在位置から後方に10バイト移動
seek($fh, -10, 1);      # 現在位置から前方に10バイト移動
seek($fh, -10, 2);      # ファイルの末尾から前方に10バイト移動

sysopen(filehandle, filename, mode, perms)

ファイルを開く低レベル I/O 関数です。mode には ">""<" ではなく、Fcntl から読み込んだ O_RDONLY(読み込みのみ)、O_WRONLY(書き込みのみ)、O_RDWR(読み書き)、O_APPEND(追記モード)、O_CREAT(無ければ作成)、O_TRUNC(開いたときにファイルを空にする) を指定します。O_CREAT を指定した場合は mode も指定します。

use Fcntl qw(:DEFAULT :mode);
my $msg = "Hello world!\n";
sysopen(my $fh, "example.txt", O_RDWR | O_CREAT, 0644) or die $!;
syswrite($fh, $msg, length($msg));
close($fh);

sysread(filehandle, scalar, length, offset)
          sysread(filehandle, scalar, length)

ファイルを読み込む低レベル I/O 関数です。ファイルから length バイト分を scalaroffset (省略時は 0)バイト目に読み込みます。read() などと同時に用いるとバッファリングの関係で混乱が生じます。通常は実際に読み込んだバイト数を、失敗時は undef を返します。

open(my $fh, "example.bin");
while ($n = sysread($fh, $buf, 1024)) {
    print "Read $n bytes.\n";
}
close($fh);

syswrite(filehandle, scalar, length, offset)
           syswrite(filehandle, scalar, length)

ファイルに書き込む低レベル I/O 関数です。scalaroffset (省略時は 0)バイト目から length バイトをファイルに書き込みます。print() などと同時に用いるとバッファリングの関係で混乱が生じます。通常は書き込んだバイト数を、失敗時は undef を返します。

open(my $fh, ">", "example.bin");
syswrite($fh, $buf, length($buf));
close($fh);

format

write(filehandle)
          write(expr)
          write

format 文で指定したフォーマットに従って出力を行います。sysread() に対応するのは syswrite() ですが、read() に対応するのは write() ではありません。レガシーな機能なのであまり使用されていません。

my $left   = "left";
my $middle = "middle";
my $right  = "right";
format STDOUT =
| @<<<<<<<<< | @||||||||| | @>>>>>>>>> |
  $left,       $middle,     $right
.
write;

formline(picture, args...)

formatwrite が内部的に使用している整形エンジンです。成形した結果は $^A 変数に格納されます。あまり使用することはありません。

my $left   = "left";
my $middle = "middle";
my $right  = "right";

my $picture = "| @<<<<<<<<< | @||||||||| | @>>>>>>>>> |";
formline($picture, $left, $middle, $right);
print "$^A\n";
$^A = "";

eof(filehandle)
          eof()

filehandle がオープンされていないか、オープンされているがファイルの終端に達している場合に 1 を返します。eof() とした場合は最後に読み込んだファイルが終端に達した場合に 1 を返します。

open my $fh, '<', 'example.txt' or die $!;
while (my $line = <$fh>) {
    print $line;
    if (eof($fh)) {
        print "End of file.\n";
    }
}
close $fh;

close(filehandle)

open() でオープンしたファイルハンドルをクローズします。スクリプトが終了する時にはファイルは自動的にクローズされるが、オープンしたファイルは使い終わったらクローズするのがお作法です。

open(my $fh, "example.txt");
while (my $line = <$fh>) {
    print $line;
}
close($fh);

stat(filehandle)
          stat(expr)
          stat scalar

ファイルのサイズや作成日付などを調べます。

($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
    $atime, $mtime, $ctime, $blksize, $blocks) = stat($file);

返却値はそれぞれ、$dev(デバイス番号)、$ino(iノード番号)、$mode(パーミッションモード)、$nlink(リンク数)、$uid(作成者のユーザID)、$gid(作成者のグループID)、$rdev(???)、$size(バイト数)、$atime(最終アクセス時刻)、$mtime(最終更新時刻)、$ctime(作成時刻)、$blksize(ブロックサイズ)、$blocks(ブロック数)を意味します。最終更新時刻を知りたい場合は次のようにします。

($mtime) = (stat($file))[9];

expr にアンダーバー(_)を指定すると、最後に実行した stat() の結果をそのまま返します。これは速度改善に役立ちます。

lstat(filehandle)
          lstat(expr)
          lstat scalar

stat() と同様ですが、シンボリックリンクファイルの際、リンク先のファイルではなく、シンボリックリンクファイル自体の情報を得ます。

($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
    $atime, $mtime, $ctime, $blksize, $blocks) = lstat($file);

fcntl(filehandle, function, scalar)

ファイルに対して様々なファンクションコールを行います。下記はファイルをノンブロッキングモードに設定する例です。詳細は各 OS の fcntl() のマニュアルを参照してください。

use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);

open(my $fh, '<', 'example.txt');
my $flags = fcntl($fh, F_GETFL, 0);
fcntl($fh, F_SETFL, $flags | O_NONBLOCK);

ioctl(filehandle, function, scalar)

ファイルに対して様々な I/O コントロールを行います。詳細は各 OS の ioctl() のマニュアルを参照してください。

require "sys/ioctl.ph";
ioctl(STDIN, &FIONBIO, 1);

binmode(filehandle)

filehandle の入出力をバイナリモードで行うようにします。UNIX では意味が無いが、Windows ではバイナリファイルを読み書きする際にはバイナリモードにしなくてはなりません。さもないと、改行コード変換(CR LF ←→ LF)が行われてしまい、バイナリデータが破損してしまいます。

open(my $fh, "example.bin");
binmode($fh);
sysread($fh, $buf, 1024);
  :

truncate(filehandle, length)
          truncate(expr, length)

指定したファイルのサイズを変更します。サポートしていないシステムでは致命的エラーとなります。

open(my $fh, "+<", "example.bin");
truncate($fh, 1024);
close($fh);

fileno(filehandle)

filehandle で示されるファイルのファイルディスクリプタを返します。これは select() などで用いられます。

$stdin = fileno(STDIN);

flock(filehandle, operation)

他のプロセスが書込み中のファイルを読み込むと、不完全なデータを読み込んでしまい、それを書き戻した時点でファイルが破壊されることがあります。これを防ぐために flock() を用いてファイルをロック(排他制御)します。

open(my $fh, "example.txt");
flock($fh, 1);
  :

operation には次の値のいずれかを指定します。(まれに、数値の異なるシステムもあるかも?)

1   読み込み宣言ロック(ブロックモード)
2   書き込み宣言ロック(ブロックモード)
5   読み込み宣言ロック(非ブロックモード)
6   書き込み宣言ロック(非ブロックモード)
8   ロック解除(アンロック)

読み込み宣言ロックは「今から私が読み込むから、他の誰も書き込むな」という宣言であり、書き込み宣言ロックは「今から私が書き込むから、他の誰も読み込んだり書き込んだりするな」という宣言です。ただし、書き込みを禁止すると言っても、flock() を使用していないプロセスの書き込みまで禁止できる訳ではありません。ブロックモードでは、自分がロックをかけることができる状態になるまでプログラムが一時停止します。非ブロックモードでは、自分がロックをかけることができたか、できなかったらすぐに真または偽を返します。flock() をサポートしていないシステムでは異常終了します。汎用性のあるプログラムを記述する場合は evalを使用するとよいです。

ファイルの書き込みロックを行う際、下記の例は2つの誤りを犯しています。

open(my $fh, ">", "outfile.txt");
flock($fh, 2);
print $fh "........";
flock($fh, 8);
close($fh);

ひとつ目は open() を行った時点で、ロックを行うよりも前にファイルサイズを 0 にしてしまう点。ふたつ目は、print による書き込みキャッシュがフラッシュされる前に flock($fh, 8) でロックを解除してしまっている点です。上記のコードは次のように書かなくてはなりません。close() を行った時やプログラムが終了する時には自動的にロックは解除されます。(ただし、2つ目の問題は最近の perl では改善されています)

open(my $fh, "+<", "outfile.txt");
flock($fh, 2);
truncate($fh, 0);
seek($fh, 0, 0);
print $fh "........";
close($fh);

ファイル操作

glob(expr)

expr にマッチするファイル名の配列を返します。

while (my $file = glob("*.txt")) {
    print "$file\n";
}

rename(oldname, newname)

ファイル名を変更します。成功すれば 1 を、失敗すれば 0 を返します。

rename("example.txt", "example.bak");

chmod(mode, filelist)

filelist で指定したファイル(複数指定可)のパーミッションを変更します。変更が成功したファイルの個数を返します。

chmod(0644, "example.txt");

chown(uid, gid, filelist)

filelist (配列指定可能)で指定したファイルのオーナーユーザーとオーナーグループを変更します。uid, gid にはそれぞれユーザーIDとグループIDを指定します。変更に成功したファイルの個数を返します。

chown($uid, $gid, "example.txt");

utime(atime, mtime, filelist)

filelist で指定したファイルのアクセス時刻 atime と更新時刻 mtime を変更し、変更に成功したファイルの個数を返します。atimemtimetime() で得られるような値を用います。

my $atime = my $mtime = time();
utime($atime, $mtime, "example.txt");

ファイルを削除します。削除に成功したファイルの個数を返します。

unlink("example.txt");

ファイルをリンクします。リンクされたファイルは実態が同じで、複数のパス名を持つファイルとなります。oldfile に既存のファイル名、newfile に新規作成する新ファイル名を指定します。成功時は 1、失敗時は 0 を返します。

link("example.txt", "example.lnk");

oldfile を示すシンボリックファイル newfile を作成します。サポートされていないシステムでは致命的エラーとなるので eval を用います。

symlink("example.txt", "example.sym");

シンボリックリンク先のファイル名を得ます。サポートされていないプラットフォームでは致命的エラーとなります。

$file = readlink("example.sym");
print "$file\n";                  # example.txt

umask(expr)
        umask()

ファイル作成時のパーミッションマスクを指定します。022 を指定すると、0777 から 022 がマスクされて 0755 となります。

umask(022);

ディレクトリ操作

mkdir(dirname, mode)

ディレクトリを作成します。mode にはディレクトリのパーミッション(通常 0755)を指定します。成功時は 1 を返します。失敗時は 0 を返し、$! が設定されます。

mkdir("mydir", 0755);

rmdir(filename)
          rmdir

ディレクトリを削除します。成功時は 1 を返します。失敗時は 0 を返し、$! を設定します。filename を省略すると $_ を参照します。

rmdir("mydir");

chdir(dirname)

カレントディレクトリ(作業フォルダ)を変更します。カレントディレクトリはプロセスが終了するまで有効で、子プロセス起動時は子プロセスに引き継がれます。区切り文字は \ よりも / を使用するのが無難です。

chdir("C:/Temp");

chroot(dirname)

このプロセスにおけるルートディレクトリを変更します。

chroot("/opt/myapp/root");

ディレクトリ読み出し

opendir(dirhandle, expr)

ディレクトリ内のファイル一覧を得るためにディレクトリをオープンし、ディレクトリハンドルを得ます。

opendir($dir, "mydir");
while ($file = readdir($dir)) {
    print "$file\n";
}
closedir($dir);

readdir(dirhandle)

ディレクトリ内のエントリ(ファイルやディレクトリなど)の一覧を得ます。スカラー変数に代入する時は次のエントリを、配列変数に代入する時は残りのエントリの一覧を返します。これ以上エントリが無い場合は undef (配列の場合はヌルリスト)を返します。

opendir($dir, "mydir");
while ($file = readdir($dir)) {
    print "$file\n";
}
closedir($dir);

telldir(dirhandle)

現在のディレクトリ位置を返します。この値は seekdir() で用いられます。

$pos = telldir($dir);

seekdir(dirhandle, pos)

readdir() で読み込むディレクトリ位置を変更します。pos には telldir() が返す値を指定します。

seekdir($dir, $pos);

rewinddir(dirhandle)

readdir() で最初から読み込めるようにします。

rewinddir($dir);

closedir(dirhandle)

opendir() でオープンしたディレクトリハンドルをクローズします。

closedir($dir);

文字列操作

q/string/

'string' の別表記。string 中に ' をエスケープなしで記述できます。/ の代わりに |(..) も使用可能です。

$msg = q/She said, "I'm ready!."/;
$msg = q|She said, "I'm ready!."|;
$msg = q(She said, "I'm ready!.");

qq/string/

"string" の別表記。string 中に " をエスケープなしで記述できます。

$msg = qq/She said, "I'm ready!."/;

qx/string/

`string` の別表記。string 中に ` をエスケープなしで記述できます。ユーザーから受け取った文字列を含むデータを迂闊に実行するとコマンドインジェクションの脆弱性問題が発生するので注意してください。

$output = qx/ls -l/;

qw/string/

文字列のリストを生成します。下記の2行は同じ意味になります。

@animals = qw(dog cat fox);
@animals = ("dog", "cat", "fox");

/pattern/

正規表現。→ 詳細

if ($name =~ /^[A-Za-z0-9]+$/) {
    print "Match!\n";
}

m/pattern/

/pattern/ の別表記。/ の代わりに | などを使用すると、pattern 中に / をエスケープなしで記述できます。

if ($file =~ m|^/usr/local/bin/|) {
    print "Match!\n";
}

qr/string/

/string/ の正規表現オブジェクトを生成します。/ の代わりに | などを使用すると、pattern 中に / をエスケープなしで記述できます。

$re = qr|^/usr/local/bin|;
if ($file =~ $re) {
    print "Match!\n";
}

s/pattern/replacement/

正規表現による文字列置換。→ 詳細

$msg = "Hello Yamada!";
$msg =~ s/Yamada/Tanaka/;
print "$msg\n";                # Hello Tanaka!

tr/searchlist/replacement/flag

y/searchlist/replacement/flag

文字置換。下記の例は aA に、bB に、cC に置換します。tr/.../.../y/.../.../ は同義。→ 詳細

$str =~ tr/abc/ABC/;
$str =~ tr/a-c/A-C/;

pos(str)

m/.../g でグローバルマッチした順番を示します。下記の例ではループをまわる度に 1, 2, 3... が表示されます。

$str = "ABC";
while ($str =~ m/([A-Z])/g) {
    print pos($str) . ": $1\n";
}

length(expr)
          length

expr で与えられる文字列の長さを返します。expr 省略時は length($\) と同じ。

$len = length("Hello!");
print "$len\n";              # 6

substr(expr, offset, length)
          substr(expr, offset)

文字列の一部を取り出します。expr で与えられる文字列のうち offset 文字から length 文字分を返します。最初の文字は通常 0 文字目ですが、$[ により変化します。offset が負の値の時は $[ に関わらず、文字列の最後から -offset 文字目(最後の文字は1文字目)から後ろ方向に length 文字分を返します。length を省略すると残りの全てを返します。substr() は式の左辺にも使用できます。

$msg = "ABCDEFG";
print substr($msg, 2, 3) . "\n";     # CDE
substr($msg, 2, 3) = "XXX";
print "$msg\n";                      # ABXXXFG

index(str, substr, position)
          index(str, substr)

文字列の中から特定の文字列を探します。文字列 strposition 番目(省略時は最初)から後方に substr を探していき、最初に現れる位置を返します。

$n = index("xxxxABCxxxxABCxxxx", "ABC");
print "$n\n";             # 4

rindex(string, substr, position)
          rindex(string, substr)

文字列の中から特定の文字列を探します。文字列 string の末尾から position 番目(省略時は末尾)から前方に substr を探していき、最初に現れる位置(先頭からの位置)を返します。

$n = rindex("xxxxABCxxxxABCxxxx", "ABC");
print "$n\n";             # 11

join(expr, list)
          join(expr, array)

list で与えられる文字列の配列を expr の値で区切りながら連結します。

$hour = 23; $min = 59; $sec = 59;
$now = join(":", $hour, $min, $sec);
print "$now\n";                       # 23:59:59

split(/pattern/, expr, limit)
          split(/pattern/, expr)
          split(/pattern/)
          split

文字列を区切り文字で分割します。正規表現 /pattern/ にマッチする部分を区切り文字として、exprで 与えられる文字列を limit を超えない範囲の個数に分割し、その配列を返します。limit を省略した場合は個数制限はありません。expr を省略した場合は $_ を分割します。/pattern/ を省略した場合はホワイトスペース(ひとつ以上の空白、タブ、または改行)で分割します。

($year, $mon, $day) = split(/-/, "2025-12-31");
print "$year/$mon/$day\n";             # 2025/12/31

sprintf(format, list)

printf() と同様のフォーマットを行いますが、ファイルへの書き出しは行わず、結果を文字列として返します。次の例は数値を文字列に変換します。

$num = 123;
$str = sprintf("%08d", $num);
print "$str\n";              # 00000123

chop(list)
          chop(string)
          chop()

文字列の最後の文字を削除して、その文字列を返します。文字列を配列で与えた場合はすべての文字列の最後の文字を削除し、最後の文字列の結果を返します。<filehandle> で読み込んだデータ末尾の改行コード(\n)を削るのに便利ですが、\r\n の時でも \n しか削らないので注意してください。引数省略時は chop($_) と同じです。

while ($line = <$fh>) {
    chop($line);
      :
}

chomp(list)

行末の改行コードを削除します。具体的には、行末のレコードセパレータ $/ にマッチする部分を削除するので、chop に比べて安全性は高いです。Perl 5 からサポートされています。

while ($line = <$fh>) {
    chomp($line);
      :
}

lc(string)

lcfirst(string)

uc(string)

ucfirst(string)

lc() は文字列全体を小文字に、lcfirst() は最初の文字のみ小文字に、uc() は文字列全体を大文字に、ucfirst() は最初の文字のみ大文字に変換したものを返します。

print(lc("JAPAN") . "\n");        # japan
print(lcfirst("JAPAN") . "\n");   # jAPAN
print(uc("japan") . "\n");        # JAPAN
print(ucfirst("japan") . "\n");   # Japan

fc(string)

Perl 5.40 では Unicode 15.1 に対応し、lc()"É""é""Σ""σ""P""p" などの小文字変換は行ってくれるようになりましたが、"ß""ss" の小文字変換は行ってくれません。fc() であれば "ß""ss" の小文字変換も行います。use 5.16use utf8 が必要です。

use v5.16;
use utf8;
$a = "STRAßE";
$b = "STRASSE";
print("LC: " . ((lc($a) eq lc($b)) ? "match\n" : "not match\n"));    # not match
print("FC: " . ((fc($a) eq fc($b)) ? "match\n" : "not match\n"));    # match

quotemeta(string)

正規表現のメタ文字などをすべてエスケープします。具体的には、[0-9a-zA-Z_] 以外の文字をバックスラッシュ(\)でエスケープします。

print quotemeta("(1+2)*(3+4)") . "\n";    # \(1\+2\)\*\(3\+4\)

時刻操作

time()

現在の時刻を得ます。グリニッジ標準時の1970年1月1日0時0分0秒からの秒数を返します。localtime()gmtime() で変換します。

$now = time();

localtime(expr)

time()stat() で得られた時刻を地方時間帯の年月日時分秒などに分解します。$sec, $min, ...はそれぞれ、秒数(0-59)、分(0-59)、時(0-23)、日(1-31)、月(0-11)、年(1900年からの年数(西暦の下2桁ではない))、曜日(日(0)-土(6))、年日数(1月1日を0とする)、$isdst(夏時間なら0以外の値)を表わします。

($sec, $min, $hour, $mday, $mon, $year,
    $wday, $yday, $isdst) = localtime(time());

gmtime(expr)

localtime() と同様ですが、グリニッジ標準時の値を返す点が異なります。

($sec, $min, $hour, $mday, $mon, $year,
    $wday, $yday, $isdst) = gmtime(time());

配列制御

sort(list)
        sort(subroutine list)
        sort { ... } list

配列の各要素をソートした結果を返します。引数で指定した配列は変更されません。以下の3パターンの使用方法があります。

@list = (3, 6, 8, 2, 9);
sub sortfunc { $a <=> $b }
@result = sort(@list);
@result = sort(sortfunc @list);
@result = sort({ $a <=> $b } @list);

この場合の sortfunc (名前は任意) などをソート関数と呼びます。ソート関数には比較要素が $a, $b という名前で渡されます。結果として正、0、負のいずれかで返すようにします。

reverse(list)

配列(または文字列)を逆順に並び替えたものを返します。結果を配列として扱うか、スカラーとして扱うかで動作が異なります。

@ans = reverse("abc", "def");     # ( "def", "abc" )が返される
$ans = reverse("abc", "def");     # "fedcba"が返される

splice(array, offset, length, list)
        splice(array, offset, length)
        splice(array, offset)

配列要素を部分削除(置換)します。array のうち、offset 番目から length 個の要素を list で置き換えます。offset は 0 から始まります。list 省略時は削除します。length 省略時は offset 番以降すべてが対象となります。

@array = (1, 2, 3, 4, 5, 6, 7, 8, 9);
splice(@array, 2, 3, 99, 98, 97);
print "@array\n";                    # 1 2 99 98 97 6 7 8 9

shift(array)
        shift()

配列の最初の要素を取り出します。取り出された要素は配列から削除されます。配列に要素が無い場合は undef を返します。

@args = ("A", "B", "C");
$arg = shift(@args);
print "$arg\n";              # A
print "@args\n";             # B C

unshift(array, list)

配列の最初に要素(配列指定可能)を追加します。arraylist が追加されます。

@args = ("A", "B", "C");
unshift(@args, "X");
print "@args\n";             # X A B C

push(array, list)

配列の最後に要素(配列指定可能)を追加します。arraylist が追加されます。

@args = ("A", "B", "C");
push(@args, "X");
print "@args\n";             # A B C X

pop(array)

配列の最後の要素を取り出します。取り出された要素は配列から削除されます。配列に要素が無い場合は undef を返します。

@args = ("A", "B", "C");
$arg = pop(@args);
print "$arg\n";              # C
print "@args\n";             # A B

grep(expr, list)
        grep { ... } list

配列から、パターンにマッチした要素を取り出します。次の例は、配列 @array の中から S で始まるものの配列を抜き出します。

@array = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
@result = grep{ /^S/ } @array;
print "@result\n";           # Sun Sat

map(block, list)
        map(func, list)

list の各要素に対して block または func が示す関数を実行します。

print(join(", ", map { $_ * 2 } (1, 2, 3)) . "\n");     # 2, 4, 6
print(join(", ", map(ord, ("A", "B", "C"))) . "\n");    # 65, 66, 67

ハッシュ制御

keys(assoc_array)

指定されたハッシュのすべてのキーの一覧を配列で返します。

foreach $key (keys(%foo)) {
    print "$key = $foo{$key}\n";
}

values(assoc_array)

指定されたハッシュのすべての値の一覧を配列で返します。

foreach $value (values(%foo)) {
    print "$value\n";
}

each(assoc_array)

ハッシュのすべての要素について処理を行います。

while (($key, $value) = each(%foo)) {
    print "$key = $value\n";
}

delete $assoc_array{key}

指定したハッシュを削除、つまり、undef の状態にします。

delete $foo{'baa'};

exists(hash_value)

指定したハッシュ要素が存在するか調べます。

my %foo;
$foo{"name"} = "Yamada";
if (exists($foo{"name"})){
    print "Exists.\n";
}

変数制御

local variables

サブルーチン、evaldo の中でローカルな変数を定義します。下記の例では、func() の中で $a を書き換えているがサブルーチン内のみで有効なローカル変数のため、グローバル変数 $a の値は変更されず、3 が表示されます。レガシーな機能で、現在では my が使用されます。

sub func {
    local($a);
    $a = 5;
}
$a = 3;
func();
print "$a\n";                 # 3

my variables

サブルーチンやブロック内のみで有効なローカル変数を定義します。

sub func {
    my $var = 5;
    :
}

our variables

パッケージ変数をスコープ内で見えるようにします。use strict している際にパッケージ変数を使用する際などに使用します。

use strict;
our $VERSION = "1.0";

state variables

最初に1度だけ初期化され、2回目以降は初期化されない変数を定義します。use feature 'state' が必要です。

use feature 'state';

sub countup() {
    state $count = 0;
    return $count++;
}

print countup()."\n";         # 0
print countup()."\n";         # 1
print countup()."\n";         # 2

defined(expr)

変数、配列、サブルーチンが定義されているかどうかを調べ、真または偽を返します。値がヌル文字(または0、または空配列)なのか、それとも定義されていないのかを調べる事ができます。いくつかの関数も undef 値を返す事があります。

defined($foo)              # False
$foo = 123;
defined($foo)              # True

undef(expr)

変数やサブルーチン名を指定して、これらを、定義されていない状態に戻します。

$foo = 123;
undef($foo);

reset(expr)

指定した名前のすべての変数をクリアします。

$foo = "123";
@foo = (1, 2, 3);
%foo = ("name" => "Yamada", "age" => 36);
reset("foo");

ref(var)

リファレンス変数 var が何を指示しているか、その型を返します。単純なスカラー値、配列、ハッシュの場合は空文字('') を返します。

use IO::Socket::INET;

$str = "ABC";
$ref_str = \$str;
$array = (1, 2, 3);
$ref_array = [1, 2, 3];
$dict = ("name" => "Yamada", "age" => 36);
$ref_dict = {"name" => "Yamada", "age" => 36};
$re = qr/^\d+$/;
$sub = sub { };
$sock = IO::Socket::INET->new();
open(my $fh, "/dev/null");

print ref($str) . "\n";               # 空文字
print ref($ref_str) . "\n";           # SCALAR
print ref($array) . "\n";             # 空文字
print ref($ref_array) . "\n";         # ARRAY
print ref($dict) . "\n";              # 空文字
print ref($ref_dict) . "\n";          # HASH
print ref($re) . "\n";                # Regexp
print ref($sub) . "\n";               # CODE
print ref($sock) . "\n";              # IO::Socket::INET
print ref($fh) . "\n";                # GLOB

tie variable, classname, list

untie variable

tied variable

変数にクラスを結びつけます。例えば下記の例では、@lines という変数に example.txt というファイルに対する Tie::File クラスを結びつけています。これにより、@lines への読み書きが直接 example.txt ファイルへの読み書きに連動します。最後の untie でファイルが閉じられます。tied は結びつけられたオブジェクトへのリファレンスを返します。cpan コマンドで Tie::File をインストールしておく必要があります。Tie::File の他にも NDBM_File でデータベースに結びつけたりなど色々なクラスが用意されています(詳細省略)。

use Tie::File;

tie @lines, "Tie::File", "example.txt";
$lines[0] = "AAA\n";
$lines[1] = "BBB\n";
$lines[2] = "CCC\n";
untie @lines;

数学関数

sin(angle)

cos(angle)

atan2(y, x)

sin() は角度 angle の sin 値、cos() は角度 angle の cos 値、atan2() は座標 $x, $y への角度を返します。角度はラジアン単位(180度=π)。

sub round { int($_[0] + 0.5); }               # 四捨五入関数
$pi = 3.141592653589793238462643383279;       # 円周率
$r = 100;                                     # 半径
$ang = 30;                                    # 角度(°)
$y = round($r * sin($ang * $pi / 180));
$x = round($r * cos($ang * $pi / 180));
print "x=$x, y=$y\n";                         # x=87, y=50
$ang = round(atan2($y, $x) / ($pi / 180));
print "ang=$ang\n";                           # 30

abs(expr)

expr の絶対値を返します。expr 省略時は abs($_) と同じ。

print abs(-123) . "\n";             # 123

sqrt(expr)

expr の平方根を返します。expr 省略時は sqrt($_) と同じ。

print sqrt(2) . "\n";                 # 1.4142135623731

log(expr)

e を基とする expr の log を返します。expr 省略時は log($_) と同じ。

print log(10) . "\n";                 # 2.30258509299405

exp(expr)

e の expr 乗を返します。expr 省略時は exp($_) と同じ。

print exp(1) . "\n";                  # 2.71828182845905

rand(expr)

0 以上、expr 未満のランダムな値(小数付き)を返します。expr 省略時は rand(1) と同じ。下記の例は、0 以上 100 未満の乱数を得ます。古いバージョンの perl では、srand() による乱数の初期化が必要です。

$num = int(rand(100));
print "$num\n";

srand(expr)

rand()の種を与えます。rand() は乱数を返すと記述されていますが、プログラム起動後は常に同じパターンの値を返します。このパターンの始まりを変更するために、プログラムの先頭で srand() を呼び出して無意味な値を指定してやります。ただし、Perl 5.004 以降は rand() 呼び出し時に srand() が自動的に呼び出されるので不要です。expr 省略時は srand(time) と同じです。

srand();
$num = int(rand(100));
print "$num\n";

データ変換

int(expr)

expr の整数部を返します。expr 省略時は int($_) と同じ。

print int(3.14) . "\n";           # 3

oct(expr)

expr が、0x で始まっていれば 16進数、0b で始まっていれば2進数、それ以外なら 8進数だと解釈してその値を返します。次の例は 0x で始まっていれば 16進数、0b で始まっていれば2進数、0で始まっていれば8進数、それ以外なら10進数と解釈します。

$num = "0xFF";
$ans = ($num =~ /^0/) ? oct($num) : $num;

hex(expr)

expr を 16進数の文字列と解釈してその値を返します。先頭が 0x で始まっていれば 0x を無視します。expr 省略時は hex($_) と同様。

$ans = hex("FF");     # 255
$ans = hex("0xFF");   # 255

ord(expr)

expr の最初の文字の ASCII コードを数値で返します。expr 省略時は $_ を見ます。例えば ord("A") は 65、ord("B") は 66 を返します。

print(ord("A") . "\n");             # 65

chr(expr)

ASCII コード expr に対応する文字を返します。expr 省略時は $_ を見ます。

print(chr(65) . "\n");              # A

scalar(expr)

expr で指定した値をスカラー値に変換して返します。

@arr = (1, 2, 3, 4);
$num = scalar(@arr);                # リストの要素数4
%foo = (a => 1, b => 2, c => 3);
$num = scalar(%foo);                # 辞書の要素数3

pack(template, list)

バイナリデータを生成します。templatelist がどんな形式のデータなのかを指定します。後ろに数値を付けるとその個数分、アスタリスク(*)をつけると list の最後まで、バイナリデータに変換します。

a  ASCII string(ヌル文字が補完される)
A  ASCII string(スペースが補完される)
b  bit string(昇順ビットオーダ)
B  bit string(降順ビットオーダ)
h  hex string(low nybble first)
H  hex string(high nybble first)
c  符号付き1バイト数値(-128 ~ 127)
C  符号無し1バイト数値(0~255)
s  符号付きshort数値(通常2バイト)
S  符号無しshort数値(通常2バイト)
i  符号付きint数値(通常4バイト)
I  符号無しint数値(通常4バイト)
l  符号付きlong数値(通常4バイト)
L  符号無しlong数値(通常4バイト)
n  short数値(ネットワークバイトオーダ)
N  long数値(ネットワークバイトオーダ)
x  ヌル文字
X  back up a byte
f  単精度浮動小数点
d  倍精度浮動小数点
p  文字列へのポインタ
u  uuencodeされた文字列
@  絶対位置までヌル文字を埋める

例えば次のように使用します。

pack("C*", 0x41, 0x42, 0x43);           # 0x41 0x42 0x43
pack("b*", "10101010");                 # 0x55
pack("a5", "abc");                      # 0x41 0x42 0x43 0x00 0x00

unpack(template, expr)

バイナリデータを解釈します。templatepack() のものと同様。

unpack("C", "A")        # AのASCIIコード0x41を返す

vec(expr, offset, bits)

文字列 expr をバイナリデータとして読み書きします。offset は先頭からの相対位置(0開始)、bits には 1, 2, 4, 8, 16, 32, 64 のいずれかを指定します。

$str = "ABC";
print(vec($str, 1, 8). "\n");          # "B"の文字コード 66
vec($str, 2, 8) = 66;                  # "C"の位置に66を書き込み
print "$str\n";                        # ABB

クラス

class className { ... }

まだ実験的機能ですが、Perl 5.38 から class が使える用になりました。下記は Person というクラスを定義しています。$name というフィールドと hello() というメソッドを持ち、コンストラクタでは $name を初期化しています。

use v5.38;
use feature 'class';
no warnings 'experimental::class';

class Person {
    field $name :param;

    method hello {
        print("Hello $name!\n");
    }
}

my $obj = Person->new(name => "Yamada");
$obj->hello();

field

クラスフィールドを定義します。:param を付加するとコンストラクタによる初期化の対象となります。

class Person {
    field $name :param;
      :
}

method

クラスメソッドを定義します。

class Person {
    method hello {
        print("Hello!\n");
    }
}

bless ...

class が登場する以前のクラス生成に使用されていた機能です。下記の $self のような参照オブジェクトをクラス名 $class と結びつけます。これにより、$object->method() のような呼び出し方が可能となります。Perl 5.38 以降ではまだ実験的機能ですが class が使用できます。

person.pl
package Person;

sub new {
    my ($class, %args) = @_;
    my $self = { name => $args{name} };
    return bless $self, $class;
}

sub hello {
    my ($self) = @_;
    print "Hello $self->{name}!\n";
}
1;
require "./person.pl";

my $obj = Person->new(name => "Taro");
$obj->hello();

プロセス制御

system(list)

list で指定した外部コマンドを実行します。その実行コマンドの戻り値が system() の戻り値となります。

system("/bin/ls -l");

fork()

子プロセスを生成し、親プロセスと子プロセスに分岐します。親プロセスの場合、$pid には子プロセスのIDが、子プロセスの場合、$pid には 0 が返ります。fork() をサポートしていないシステムもあり、無理に使用すると perl が異常終了します。

if ($pid = fork()) {
    print "This is parent process.\n";
} else {
    print "This is child process.\n";
}

pipe(readhandle, writehandle)

パイプの両端を作成します。fork() と組み合わせることで、パイプで連結された親子プロセスを生成できます。

pipe(my $reader, my $writer) or die "pipe failed: $!";
my $pid = fork();
die "fork failed: $!" unless defined $pid;
if ($pid) {
    # Parent process
    close $reader;
    print $writer "Hello child\n";
    close $writer;
    waitpid($pid, 0);
} else {
    # Child process
    close $writer;
    my $msg = <$reader>;
    print "Child received: $msg";
    close $reader;
    exit;
}

readpipe(command)

コマンドを起動し、その出力結果を読み取ります。文字列で受け取る方法と、文字列配列で受け取る方法があります。

$output = readpipe("ls -l");
print $output;

@lines = readpipe("ls -l");
foreach my $line (@lines) {
    print $line;
}

wait()

任意の子プロセスの終了を待ちます。いずれかの子プロセスが終了するとそのプロセスIDを返します。プロセスの終了ステータスは $? に格納されます。子プロセスが存在しない場合は -1 を返します。

$pid = wait();

waitpid(pid, flags)

プロセスIDを指定して子プロセスの終了を待ちます。pid に 0 を指定すると同じプロセスグループの任意の子プロセス、-1 を指定すると子プロセスの内最初に終了したもの、-N を指定するとプロセスグループIDが N のものを待ちます。flags に 0 を指定するとブロッキングモード、WNOHANG を指定するとノンブロッキングモードとなります。

# ブロッキングモード
waitpid($pid, 0);

# ノンブロッキングモード
my $kid;
do {
    $kid = waitpid(-1, WNOHANG);
} while $kid > 0;

getppid()

親プロセスIDを返します。

$ppid = getppid();

getpgrp(pid)

setpgrp(pid, pgrp)

プロセスグループを取得・設定します。

$pgrp = getpgrp();
setpgrp($pgrp);

getpriority(which, who)

setpriority(which, who, priority)

プロセスの nice 値(-20~19)を設定・取得します。

my $prio = getpriority(PRIO_PROCESS, $$);
print "$prio\n";
setpriority(PRIO_PROCESS, $$, 19);

times

プロセスの CPU 消費時間(秒数)を返します。$user は自プロセスのユーザー時間、$system は自プロセスのシステム時間、$cuser は子プロセスのユーザー時間、$csystem は子プロセスのシステム時間を意味します。

my ($user, $system, $cuser, $csystem) = times;
print "user=$user\n";
print "system=$system\n";
print "cuser=$cuser\n";
print "csystem=$csystem\n";

シグナル

kill(sig, list)

list で示すプロセスにシグナルを送ります。詳細は OS のシステムコールマニュアルを参照。

kill('TERM', $pid);

alarm(expr)

expr 秒後にアラームシグナル(SIGALRM)を発行します。SIGALRM は、$SIG{'ALRM'}="handle"; で捕獲します。再設定したり expr に 0 を指定すると、以前の設定はキャンセルされ、以前の設定の残り時間が返されます。OS によってはサポートされていません。

$SIG{'ALRM'} = "sigalrm";
sub sigalrm { print "ALARM!!\n"; }
alarm(5);

ソケット

socket(socket, domain, type, protocol)

ネットワーク通信のためのソケットを作成します。メッセージを受信するサーバーと、メッセージを送信するクライアントのサンプルを下記に示します。

server.pl
use Socket;

$port = 8888;
$addr = sockaddr_in($port, INADDR_ANY);
socket($sock, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
bind($sock, $addr);
listen($sock, 5);
accept($client, $sock);
$msg = <$client>;
print "$msg\n";
close($client);
close($sock);
client.pl
use Socket;

$host = "127.0.0.1";
$port = 8888;
$addr = sockaddr_in($port, inet_aton($host));
socket($sock, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
connect($sock, $addr);
print $sock "Hello!";
close($s);

bind(socket, name)

ソケットに名前をつけます。

$port = 8888;
$addr = sockaddr_in($port, INADDR_ANY);
bind($sock, $addr);

listen(socket, queuesize)

サーバー用ソケットを待ち合わせ状態にします。queuesize には多重待ち合わせの数(通常5個程度)を指定します。

listen($sock, 5);

accept(new_socket, socket)

クライアントからの接続要求を受け付けます。new_socket にはクライアントと接続された新しいソケットが設定されます。

accept($newsock, $sock);

connect(socket, name)

クライアント側からサーバー側に接続要求を出します。

connect($sock, $addr);

send(socket, msg, flags, to)
          send(socket, msg, flags)

ソケットにデータを送信します。接続済の場合は to は不要。UDP 等で未接続の場合は to に相手先アドレスを指定します。flags の詳細は sendto を参照してください。

send($sock, $buf, 0);              # TCP等で接続済の場合
send($sock, $buf, 0, $addr);       # UDP等で未接続の場合

recv(socket, scalar, length, flags)

ソケットからデータを受信します。scalar にはメッセージを受信する変数を、length には受信する最大バイト数を指定します。flags の詳細は recv を参照してください。

recv($sock, $buf, 1024, 0);

shutdown(socket, how)

ソケットの送信を終了します。

shutdown($sock, 0);     # 受信のみをクローズ
shutdown($sock, 1);     # 送信のみをクローズ
shutdown($sock, 2);     # 受信/送信両方をクローズ

select(rbits, wbits, ebits, timeout)

複数のソケットやファイルディスクリプタの多重待ちを行います。rbits は受信待ちリスト、wbits は送信待ちリスト、ebits は緊急送信待ちリスト、timeout にはタイムアウト時間を秒単位で指定します。下記は、標準入力のみを5秒タイムアウトで受信待ちします。

my $rin = '';
vec($rin, fileno(STDIN), 1) = 1;
print "Waiting 5 seconds...\n";
if (select(my $rout = $rin, undef, undef, 5)) {
    my $line = <STDIN>;
    chomp $line;
    print "Input: $line\n";
} else {
    print "Timeout\n";
}

socketpair(socket1, socket2, domain, type, protocol)

名前の無いソケットペアを作成します。親プロセスと子プロセスで共有することで、親子間のソケット通信を可能とします。

use Socket;

socketpair($sock1, $sock2, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
if ($pid = fork()) {
    close $sock1;
    send($sock2, "Hello!", 0);
    print "Send message to server.\n";
} else {
    close $sock2;
    recv($sock1, $buf, 1024, 0);
    print "Receive message from client: $buf\n";
    waitpid($pid, 0);
}

getsockname(socket)

自分側のソケットの名前(アドレス情報)を得ます。

$addr = getsockname($sock);
($port, $host) = sockaddr_in($addr);
$host = inet_ntoa($host);
print "host=$host, port=$port\n";

getpeername(socket)

相手側のソケットの名前(アドレス情報)を得ます。

$addr = getpeername($sock);
($port, $host) = sockaddr_in($addr);
$host = inet_ntoa($host);
print "host=$host, port=$port\n";

setsockopt(socket, level, optname, optval)

getsockopt(socket, level, optname)

ソケットにオプション設定・参照を行います。詳細は OS の setsockopt() を参照してください。

use Socket;
socket($sock, PF_INET, SOCK_STREAM, getprotobyname("tcp"));
setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, 1);
$val = getsockopt($sock, SOL_SOCKET, SO_REUSEADDR);
$flag = unpack("i", $val);
print "$flag\n";

gethostbyname(name)

ホスト名からIPアドレスを検索します。

use Socket;
$host = gethostbyname("www.example.com");
$host = inet_ntoa($host);
print "$host\n";

gethostbyaddr(addr, addrtype)

IPアドレスからホスト名を逆引きします。

use Socket;
$host = inet_aton("127.0.0.1");
$host = gethostbyaddr($host, PF_INET);
print "$host\n";

getnetbyname(name)

ネットワーク名からネットワークエントリを参照します。

my ($name, $aliases, $addrtype, $net) = getnetbyname("loopback");
$net = join(".", unpack("C4", pack("N", $net)));
print "name      = $name\n";
print "aliases   = $aliases\n";
print "addrtype  = $addrtype\n";
print "net       = $net\n";

getnetbyaddr(addr, addrtype)

アドレスからネットワークエントリを参照します。

use Socket;

@a = split(/\./, "127.0.0.0");
$netaddr = ($a[0] << 24) | ($a[1] << 16) | ($a[2] << 8) | $a[3];
my ($name, $aliases, $addrtype, $net) = getnetbyaddr($netaddr, PF_INET);
$net = join(".", unpack("C4", pack("N", $net)));
print "name      = $name\n";
print "aliases   = $aliases\n";
print "addrtype  = $addrtype\n";
print "net       = $net\n";

getservbyname(name, proto)

getservbyport(port, proto)

サービス名からポート番号、ポート番号からサービス名を検索します。

$port = getservbyname("http", "tcp");
print "$port\n";                       # 80
$service = getservbyport(80, "tcp");
print "$service\n";                    # http

getprotobyname(name)

getprotobynumber(number)

プロトコル名からプロトコル番号、プロトコル番号からプロトコル名を検索します。

$num = getprotobyname("tcp");
print "$num\n";                 # 6
$proto = getprotobynumber(6);
print "$proto\n";               # tcp

sethostent(stayopen)

gethostent()

endhostent()

setnetent(stayopen)

getnetent()

endnetent()

setservent(stayopen)

getservent()

endservent()

setprotoent(stayopen)

getprotoent()

endprotoent()

ホストエントリ、ネットワークエントリ、サービスエントリ、プロトコルエントリを参照する低レベル関数群です。詳細説明省略。

メッセージ

msgctl(id, cmd, arg)

msgget(key, flags)

msgsnd(id, msg, flags)

msgrcv(id, var, size, type, flags)

メッセージ関連関数です。詳細は OS のマニュアル参照。

セマフォ

semctl(id, semnum, cmd, arg)

semget(key, nsems, flags)

semop(key, opstring)

セマフォ関連関数です。詳細は OS のマニュアル参照。

共有メモリ

shmctl(id, cmd, arg)

shmget(key, size, flags)

shmread(id, var, pos, size)

shmwrite(id, string, pos, size)

共有メモリ関連関数です。詳細は OS のマニュアル参照。

データベース

dbmopen(assoc_array, dbname, mode)

dbmclose(assoc_array)

データベース関連関数です。詳細は OS のマニュアル参照。レガシーな機能なので現在ではあまり利用されていません。代わりに DBI などが利用されています。

ユーザー・グループ

getlogin()

ログインユーザー情報を返します。

getpwnam(name)

getpwuid(uid)

ユーザー名・ユーザーIDでパスワードエントリを参照します。

setpwent()

getpwent()

endpwent()

パスワードエントリを参照する低レベル関数。

getgrnam(name)

getgrgid(gid)

グループ名・グループIDでグループエントリを参照します。

setgrent()

getgrent()

endgrent()

グループエントリを参照する低レベル関数。

その他

syscall(list)

第1引数で指定したシステムコールを呼び出します。第2引数以降はシステムコールへの引数(最大14個)。

require 'syscall.ph';
$str = "Hello!";
syscall(SYS_write(), fileno(STDOUT), $str, length($str));

crypt(passwd, salt)

利用者のパスワードをファイルに保存する際、そのまま保存しておくと危険なので、crypt() でハッシュ化を行ってから保存します。ハッシュ化したパスワードから元のパスワードを復元することは困難(非可逆性)ですが、元のパスワードをチェックすることは容易にできます。解読を困難にするために、salt にはドット(.)、スラッシュ(/)を含む2文字の英数文字をランダムに指定します。この2文字は暗号化されたパスワードの最初の2文字となります。2文字目より後ろは無視されます。

# パスワードを "hi.mi.tu" とする
$passwd = "hi.mi.tu";

# ハッシュ化したパスワード($epasswd)を得る
@salts = ( "A".."Z", "a".."z", "0".."9", ".", "/" );
$salt = $salts[int(rand(64))] . $salts[int(rand(64))];
$epasswd = crypt($passwd, $salt);
print "epasswd=$epasswd\n";

# ハッシュ化したパスワードでパスワードをチェックする
$passwd = "hi.mi.tu";
$epasswd = "ZpoK9sz7yGHRo";
if ($epasswd eq crypt($passwd, $epasswd)) {
    print "Match!!\n";
}

MD5 がサポートされているシステムでは、salt に、"$1$" で始まる 8文字($1$ を含めて11文字)を指定することにより、MD5 を使用できます。DES よりも安全度が高いです。(補足:現在では MD5 も危険で、もっと強度の強いアルゴリズムが必要とされます)

study(scalar)

Perl 5.16 以前ではスカラー値のインデックスを作成ていました。現在のバージョンではなにもしません。

all {...} list

配列の各要素に対してブロックを実行し、その結果がすべて真の場合は真を、さもなくば偽を返します。これはまだ実験的な機能で keyword_all 機能が有効になっている場合のみ使用できます。

my @strings = ("A", "B", "C");

if (all { length $_ } @strings) {
    say "Every string is non-empty";
}

any {...} list

配列の各要素に対してブロックを実行し、その結果がひとつでも真の場合は真を、さもなくば偽を返します。これはまだ実験的な機能で keyword_any 機能が有効になっている場合のみ使用できます。

my @strings = ("A", "B", "C");

if (any { length $_ } @strings) {
    say "Every string is non-empty";
}