ノリブログ?

perlで刺身の上にたんぽぽを載せるスクリプトを書く

カテゴリー:perl

経緯

南部製作所でアルバイトしている坂本です。

今週アルバイトの時間がとれなさそうで、それを南部製作所代表の河野さんに報告すると
「じゃあアルバイトに変わりに何かバイトで使う技術を勉強してきたら、アルバイト代支給します。」
とのこと。

テーマは何にしようかなと考えて正規表現、perl、シェルスクリプトぐらいが候補にあがりました。
今、Webアプリケーションの開発はPHPで行っており、perlはほとんど触れたことがありません、、。

perlを使えるようになっておけばテストスクリプトやターミナルから実行する簡単なスクリプトを作るときに、手早くできるようになりそうなのでperlの勉強をすることにしました。

話し合った結果、勉強時間が数時間ぐらいしかとれないので達成目標はとりあえず。。。
「刺身にたんぽぽをのせるレベル」になること。

そして一週間後

「はじめてのperl」を9章ぐらいまで読みました。
簡単なファイル操作スクリプトなどは書けるようになったと思います。

で、ちゃんと勉強できたかどうか試すために与えられた課題は

  1. ディレクトリの中に、たんぽぽの画像ファイル(tanpopo.gif)と複数の刺身の画像ファイルがある
  2. 刺身ファイルはjpgファイルでありファイル名中に「sashimi」がはいっている
  3. 刺身画像とたんぽぽ画像を合成して「刺身の上にたんぽぽを載せる」スクリプトを書け

という課題。。。たしかに達成目標そのままでした。
ということで以下のようなスクリプトを書きました。

実行方法:

# ls | perl filename.pl

正規表現でファイルをチェックをするところがサブルーチン化せずにコピペでつかってたり、use strictやってなかったりと、なかなか目にあまるところがありますが、時間不足と練習不足です。。。
これからperlを使いながら慣れて行きたいと思います。
注:下のスクリプトでは実行前にtanpopo.gifのマスクファイル,mask.pbmを作成しておく必要があります。

 

#/usr/bin/perl
chomp ( @files = <>);

$t_image = "tanpopo.gif";

print "grep sashimi file....\n";
foreach $_ (@files){
if ($_ =~ /sashimi|sasimi/i){
print " [OK]:".$_;
print "\n";
push(@sashimi,$_);
}else{
print " [NG]:".$_;
print "\n";
}
}
print "\n";


print "sashimi list:
";
foreach $_ (@sashimi){
print " ".$_;
print "\n";
}
print "\n";


print "grep jpg file....\n";
foreach $_ (@sashimi){
if ($_ =~ /jpg|jpeg/i){
print " [OK]:".$_;
print "\n";
push(@s_images,$_);
}else{
print " [NG]:".$_;
print "\n";
}
}
print "\n";

print "sashimi jpg file list:
";
foreach $_ (@s_images){
print " ".$_;
print "\n";
}
print "\n";
print "genereting file.....\n";
$image_num = 0;
foreach $_ (@s_images){
system("jpegtopnm $_ | pnmscale -xsize=200 > s_tmp");
system("giftopnm $t_image | pnmscale -xsize=100 > t_tmp");
system("pnmcomp -alpha mask.pbm t_tmp s_tmp | pnmtojpeg > generetedimg$image_num.jpg");
$image_num++;
}

ユーザー領域にインストールしたcpanをシェル以外から実行したときの問題点

カテゴリー:Linux

ユーザー領域にインストールしたcpanをシェル以外から実行したときの問題点

cpanのインストールディレクトリをユーザ領域に設定することで ルート権限を持たないユーザでもcpanライブラリを利用することができる。
参考URL:

注意しなければいけないのはライブラリの保存場所の環境変数を設定しておく必要があること。

例えばbashであれば、インストールしたディレクトリが/home/user/perllibだとすると

export PERL5LIB=/home/user/perllib

としてライブラリを指定する必要がある。
(いちいち打ち込まなくても.bashrcを設定しておけば大丈夫)

しかし、この方法でCrypt::CBCをインストールした後、perlプログラムをbash以外から実行しようとした時、環境変数の設定が上の方法だと通らないことに気づいた。
(今回はメールの自動応答プログラム作成のため.forwardから実行するようにしていた、詳細はこの記事を参考に)

プログラム中に以下のようなことを試してみたがダメだった。

exec("export PERL5LIB=/home/user/perllib");
$ENV{"PERL5LIB"} = "/home/start/perllib";

そこで環境変数を通さずにローカルにインストールしたライブラリを読み込む方法を調べてみた。

環境変数を通さずにローカルにインストールしたライブラリを読み込む方法

プログラムを実行するときのカレントディレクトリにperlのライブラリディレクトリ(perllib)がインストールされている場合は

use perllib::Crypt::CBC

とすれば実行することができる。

ただし今回は.forwardが実行するのでカレントディレクトリがインストールディレクトリと一致しなく、ディレクトリの移動もできなかったため、上の方法では動作しなかった。

最終的にperlの-Iオプションでライブラリのパスが指定できることがわかり

これで対応した。 .forwardで実行する部分を以下のように書き換えた。

/usr/bin/perl -I /home/user/perllib ~/filename.pl