Contents
Windowsで開発
Active Perl
http://www.activestate.com/activeperl/downloads
EPIC(Eclipseプラグイン)
http://www.epic-ide.org/updates/をEclipseに追加してインストールする
基本文法
Hello World
use strict; use warnings; print("Hello World\n");
基本ファイル構成
use strict; use warnings; my $TRUE = 1; my $FALSE = 0; sub main { } main();
コメント
# comment
変数
共通単値変数
- 宣言
my $i=0; my $s="a";
- 代入
$i=1; $s="b";
- 参照
print("$i\n"); print("$s\n");
真偽値
真偽値はないので、次のようにして使用する。
# グローバルに宣言 my $TRUE = 1; my $FALSE = 0; # ... if($bool == $TRUE) { }
順序配列
- 宣言
my @list1 = (); my @list2 = (1,2,3);
文字列の場合
my @array = qw(a b c);
- 要素表示
print "@list\n";
- 後方追加
@list = (@list, 1);
- 代入
$list[$i] = 100;
- 配列長
my $len = @list;
- 参照
print($list[$i]);
連想配列
- 宣言
my %dictionary;
- 代入
$dictionary{$key1}{$key2} = 1;
- 存在確認
exists( $dictionary{$key1}{$key2} )
- 参照
print($dictionary{$key1}{$key2});
- 順序参照
foreach my $key1 ( keys %dictionary )
集合(Set)
perlでは直接集合は扱えないので、次の関数を利用する。
配列要素の重複排除
比較演算
数値一致
$int1 == $int2
数値不一致
$int1 != $int2
数値大小
$int1 < $int2
$int1 <= $int2 $int1 > $int2
$int1 >= $int2
文字列一致
$str1 eq $str2
文字列不一致
$str1 ne $str2
正規表現一致
$str1 =~ /(.*)/ $result = $1
OR
$int1==$int2 || $int3!=$int4
AND
$int1==$int2 && $int3!=$int4
NOT
not $int1==$int2
検査
読み込み可能
if(-r "file")
書き込み可能
if(-w "file")
実行込み可能
if(-x "file")
存在する
if(-e "file")
ファイルが存在する
if(-f "file")
ディレクトリが存在する
if(-d "file")
サイズが0
if(-z "file")
サイズが0より大きい
if(-s "file")
my $size = -s “file”;
のようにしてサイズ取得を可能
シンボリックリンクが存在する
if(-l "file")
制御構文
for
for(my $i=0;$i<10;$i++) { print("$i\n"); }
for each
- 配列変数から
foreach my $next (@list) { }
- コマンド結果から
foreach my $next (`ls`) { chomp($next); }
while
while ($i < 10) { print("$i++\n"); }
break
last;
continue
next;
if
if文では一行しか実行部分がなくても必ず{}が必要である。
if(@ARGV==0) { die "set arg for configuration path\n"; }
if else
if() { } elsif() { } else { }
switch case
存在しない
文字列操作
連結
my $concat = $str1.$str2;
部分切り取り
my $substring = substr($str, $start, $end);
置換
$str =~ s/abc/123/g;
関数
sub funcA { my $arg1 = $_[0]; my $arg2 = $_[1]; return $arg1.$arg2; } my $concat = funcA("ABC", "DEF");
コマンドライン引数
配列変数 @ARGV で与えられる
- 例
引数の数のチェック
if(@ARGV==0) { die "set arg for configuration path\n"; }
テキストファイル操作
オープン
open( FILE, "file.txt" ) or die "Can't Open File.\n";
リード
while( my $line = <FILE> ) { chomp($line); print("$line\n"); }
クローズ
close(FILE);
書き込みオープン
ロックはされないので多重書き込みに注意。
ファイルがない場合は自動で作成される。
open( FILE, ">", "file.txt" ) or die "Can't Open List File.\n";
追記書き込みオープン
ロックはされないので多重書き込みに注意。
ファイルがない場合は自動で作成される。
open( FILE, ">>", "file.txt" ) or die "Can't Open List File.\n";
ライト
print(FILE "ABC");
※バッファリングされるため、closeを行うことで、実際に書き込まれる。
ロック
ブロック状態でロックした場合は、ロックされていればロック解除まで待つ。
非ブロック状態でロックした場合は、ロックされていれば0($FALSE)を返す。
読み込みロックの場合は書き込みのみを禁止し、読み込みを許可する(共有ロック)。
ロックの解除は明示的に行うことも可能であるが、クローズすると自動で解除される。
※二重にアンロックしてはいけないのでクローズした後にはアンロック不可。
- ブロックするパターン
my $FILELOCK_SHARED_WITH_BLOCK=1; my $FILELOCK_EXCLUSIVE_WITH_BLOCK=2; my $FILELOCK_SHARED_WITHOUT_BLOCK=5; my $FILELOCK_EXCLUSIVE_WITHOUT_BLOCK=6; my $FILELOCK_RELEASE=8; open(FILE, ">>".$FILE_PATH); flock(FILE, $FILELOCK_EXCLUSIVE_WITH_BLOCK); # 書き込み処理 clos(FILE);
- ブロックしないパターン
my $FILELOCK_SHARED_WITH_BLOCK=1; my $FILELOCK_EXCLUSIVE_WITH_BLOCK=2; my $FILELOCK_SHARED_WITHOUT_BLOCK=5; my $FILELOCK_EXCLUSIVE_WITHOUT_BLOCK=6; my $FILELOCK_RELEASE=8; my $LOCKWAIT_COUNT=10; my $LOCKWAIT_TIME=1; open(FILE, ">>".$FILE_PATH); for(my $i=0;$i<$LOCKWAIT_COUNT;$i++) { my $result=flock(FILE, $FILELOCK_EXCLUSIVE_WITH_BLOCK); if($result == $FALSE) { if($i+1 == $LOCKWAIT_COUNT) { die "Can't Open File.\n"; } sleep($LOCKWAIT_TIME); } else { last; } } # 書き込み処理 clos(FILE);
ネイティブコマンド実行
my @result1 = `ls $optionByPerl`; my $result2 = `date`; chomp($result2); print("$result2\n");
標準関数
文字列系
chomp($str) – void
与えた文字列の末尾に改行文字があれば削除する。
テキストファイル読み込み時によく使用する。
返り値代入は不要。
length($str) – int
文字列長を求める
ファイル系
unlink
ファイルを削除する
- 書式
unlink($filepath) - int(削除した個数)
その他
localtime() – ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
現在時刻を求める
- 例
my @DAY_OF_WEEK = ('日', '月', '火', '水', '木', '金', '土'); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon += 1; print("$year年$mon月$mday日($dayOfWeek[$wday]) $hour時$min分$sec秒\n");
sleep
指定秒間動作停止する。
- 書式
sleep($second);
- 例
10秒間動作を停止する。
sleep(10);
CGI
環境構築
- Apacheのインストールを行う
- Apacheインストールディレクトリのcgi-binディレクトリに移動する
- perlで記述されたCGIを作成する
Hello World
#!/usr/bin/perl print("Content-type: text/html\n\n"); print("Hello World");
Tips
フィルターツール
syslogのtail -Fによるリアルタイムチェック等で使用する
use strict; use warnings; my $TRUE = 1; my $FALSE = 0; while(<>) { if($_ =~ /([^ ]+ [0-9]+ [0-9:]+) ([^ ]+) .*PACKETLOG-6-INGRESS_PKTLOG.*L3 Deny.*Proto=([A-Z]+).*SA=([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*DA=([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*srcPort=([0-9]+).*dstPort=([0-9]+)/) { my $time = $1; my $host = $2; my $protocol = $3; my $srcIP = $4; my $dstIP = $5; my $srcPort = $6; my $dstPort = $7; $srcIP = `printf "%16s" $srcIP`; $dstIP = `printf "%16s" $dstIP`; $srcPort = `printf "%6s" $srcPort`; $dstPort = `printf "%6s" $dstPort`; print("$time $host : ACL Deny $srcIP:$srcPort -> $dstIP:$dstPort ($protocol)\n"); } else { print($_); } }
配列要素の重複排除
sub uniqueArray { my %seen; grep !$seen{$_}++, @_; }
@array = uniqueArray(@array);
Pingツール
IPアドレスかホスト名のリストファイルを引数に与える
use strict; use warnings; use Net::Ping; my $TRUE = 1; my $FALSE = 0; my $TIME_OUT=0.2; my $SLEEP=1; if(@ARGV==0) { die "No ping list file as argument\n"; } open( FILE, $ARGV[0] ) or die "Can't open list file : $ARGV[0].\n"; my @list = (); while( my $line = <FILE> ) { chomp($line); @list = (@list, $line); } close(FILE); my $ping = Net::Ping->new("icmp"); while ($TRUE) { my ($sec,$min,$hour) = localtime(time); $sec = "0".$sec; $sec = substr($sec, length($sec)-2); $min = "0".$min; $min = substr($min, length($min)-2); $hour = "0".$hour; $hour = substr($hour, length($hour)-2); print("[[$hour:$min:$sec]]\n"); foreach my $host (@list) { if($ping->ping($host, $TIME_OUT)) { print "$host\tOK\n"; } else { print "$host\txxx\n"; } } print("-------------------------------\n"); sleep($SLEEP); }