パターンにマッチした以降の行のみを出力するワンライナー
perl -ne '$f =1 if /pattern/; print if $f;' sample.txt
Zabbix::APIを使ってzabbixに登録されているホストを知る
統合監視ツールzabbixにはWebUI以外にJSON-RPCによるAPIが用意されておりまして、 このAPIを叩くためのcpanモジュールZabbix::APIを使う練習をしてみます。
Loginする
use Zabbix::API; my $zbx = Zabbix::API->new( server => 'http://example.com/zabbix/api_jsonrpc.php', verbosity => 0, ); eval { $zbx->login(user => 'admin',password => 'MyPass') }; if ($@) { die "Couldn't login : $@"; }
ホストのリストを取得する
fetchメソッドを使います。
my $hosts = $zbx->fetch('Host'); foreach my $h (@{$hosts}) { print Dumper ($h->data); }
ホストグループを限定して取得するなら
my $hosts = $zbx->fetch('Host', params => { groupids => 8 } ); foreach my $h (@{$hosts}) { print "Host name :".$h->data->{name}; print "\n"; }
参考サイト
cpan https://metacpan.org/pod/Zabbix::API
Zabbix 公式 https://www.zabbix.com/documentation/2.2/manual/api
Date::Calcを使って今月の日数を知る
今月は何日間あるか、日数を知りたい。 そんな時にはDate::Calcに丁度よいモノが。
use Date::Calc qw(:all); my ($year, $month, $day) = Today(); my $days = Days_in_Month($year, $month); print "$year - $month - $day\n $days days in this month.\n";
これで行けます。
IPv4アドレスのような何かにマッチする正規表現
量指定子(quantifier)の復習
0回以上の繰り返しは「*」、1回以上の繰り返しは「+」、n回以上m回以下の繰り返しは「{n,m}」と書きます。 1~3ケタの数字は「¥d{1,3}」と書くとよろしい。
IPv4アドレスのような何か
とりあえず以下のように書くとよろしい。
(\d{1,3}\.){3}\d{1,3}
数字1~3ケタとピリオド、これを3回繰り返して最後にもう一度数字。 あくまで「最大3ケタ」であって、255を超えるような実際にはIPv4アドレスでは有り得ない数字にもマッチしてしまいますが、 ログファイルの検索などで「とりあえずその場をしのぐ」にはこれで十分使えそうです。
元ネタ
Famous Perl One-Liners Explained, Part VII: Handy Regular Expressions
CGI::Application::Plugin::DBHを使ってデータベースのテーブル内容を表示してみる
データベースに接続する
前回に引き続きCGI::Applicationの練習をいたします。 データベースにアクセスするための機能がPlug-inにありまして、これを使います。 cgiapp_init の中でDBに接続するコードを書きます。
use base 'CGI::Application'; use CGI::Application::Plugin::Session; use CGI::Application::Plugin::DBH (qw/dbh_config dbh/); sub cgiapp_init { my $self = shift; my $dbname = "db"; my $dsn = "DBI:Pg:dbname=$dbname"; my $dbUser = "user"; my $dbPass = "pass"; $self->dbh_config($dsn, $dbUser, $dbPass); }
HTML::Templateを使う
CGI::ApplicationはデフォルトでHTML::Templateを使えるようになっていまして、 これを使って表示させるとします。 setupの中でテンプレートファイルの所在を指定します。
sub setup { my $self = shift; $self->start_mode('listview_mode'); # 略 $self->tmpl_path('/some/path/to/template'); }
DBのテーブルを表示する
テーブルtblHogeの中身をlistview_modeというrun_modeで表示させるとします。
sub listview_mode { my $self = shift; my $template = $self->load_tmpl('listview.tmpl'); my $sql = 'SELECT hoge_id, hoge_time, hoge_title from tblHoge LIMIT 5'; my $sth = $self->dbh->prepare($sql); $sth->execute; my @rows; my ($hoge_id, $hoge_time, $hoge_title); $sth->bind_columns(\($hoge_id, $hoge_time, $hoge_title)); while ($sth->fetch) { push @rows, { HOGE_ID => $hoge_id, HOGE_TIME => $hoge_time, HOGE_TITLE => $hoge_title, }; } $template->param(LISTVIEW => \@rows); return $template->output; }
テンプレートファイルlistview.tmplは以下のような感じ。
<html> <head> <meta charset="utf-8"> <title>Hoge</title> </head> <body> <table> <TMPL_LOOP NAME="LISTVIEW"> <tr> <td><TMPL_VAR NAME="HOGE_ID"></td> <td><TMPL_VAR NAME="HOGE_TIME"></td> <td><TMPL_VAR NAME="HOGE_TITLE"></td> </tr> </TMPL_LOOP> </table> </body> </html>
昔は使えたかもしれない書き方
Web検索していると昔のブログ記事などで 「selectall_hashref(あるいはfetchrow_hashref)が返すリファレンスをそのままテンプレートに渡してOK!」 といったような記述に出会うことがありますが、少なくとも今はそんなことはできません。 DBIのメソッドの仕様が Ver.1.15 ~ 1.20の付近で変わった?とのこと。
CGI::Applicationを練習するための最小に近いコードを書いてみる
CGI::Applicatioin
もっと他のフレームワークが今の流行なのかもしれませんが、 温故知新という言葉もあります。 CGI::Applicationを使って文字通りCGIアプリを作るお勉強をしようと思い立ったのです。
最小構成に近い形ということで、テキストボックスに文字列を入力すると 「hoge」を「fuga」に置換して表示するWebアプリ(?)を書いてみます。
.cgiファイル
本体はMyWebApp.pmというファイルに格納してWebサーバーのDocumentRootの外に置きます。 クライアントがアクセスする.cgiファイルは次の通り。
#!/usr/bin/perl use strict; use warnings; use lib "/path/to/CGIApp"; use MyWebApp; my $webapp = MyWebApp->new(); $webapp->run();
MyWebApp.pmファイル
冒頭部分(setup)
package MyWebApp; use base 'CGI::Application'; use strict; use warnings; sub setup { my $self = shift; $self->start_mode('mode1'); $self->run_modes( 'mode1' => 'shform', 'mode2' => 'shresult', ); }
入力フォームがmode1、結果表示画面がmode2です。
入力フォーム
sub shform { my $self = shift; my $q = $self->query(); my $output = ''; $output .= $q->start_html(-title => 'My Web App'); $output .= $q->start_form(); $output .= $q->textfield(-name => 'fruits'); $output .= $q->hidden(-name => 'rm', -value => 'mode2'); $output .= $q->submit(); $output .= $q->end_form(); $output .= $q->end_html(); return $output; }
hiddenでrmをmode2としてサーバーに渡します。
結果表示
sub shresult { my $self = shift; my $q = $self->query(); my $fruits = $q->param('fruits'); my $output = ''; $output .= $q->start_html(-title => 'My Web App - Results'); $fruits =~ s/hoge/fuga/; $output .= $fruits; $output .= $q->end_html(); return $output; } 1;
これだけです。 本当はもっと複雑なことをやらせたいものですが、 まずは練習ということでココまで。