Archive for the ‘programming’ Category

wordpressで日本語ファイル名の写真はNG?

火曜日, 1月 26th, 2010

先のmooの名刺の記事で「写真.jpg」というファイル名の画像をwordpressにアップロードしたら,サムネイルが作成されないという問題に出くわした.

まずファイルはアップロードできている様子を確認してもらいたい.
ファイルはアップロードできているが..

その状態で,uploadされた先のフォルダの様子は以下のようになっていた.

console

写真.jpgは確かに存在するが,そのサムネイルにあるべきファイル名の日本語が抜け落ちているために,サムネイルのリンク指定(通常,「写真-320×240.jpg」などのファイル名になる)ができなくなっている.

どうも日本語ファイル名を考慮していないような感じがするな.mb系の関数を使ってない感じ.今つかっているのは最新じゃないから,最新の2.9.1だったら解消されているのかな?これからwordpressのソースを確認する.

ssh接続時のコンソールの解像度(行数)ずれにはresizeを使おう

土曜日, 12月 5th, 2009

自分のサーバにOSXからssh経由でログインすると、次の画像のようにOSX側とサーバ側でコンソールの解像度(行数)が違い、ちぐはぐなコンソールになる時がある。

ピクチャ 1

この問題は「resize」というツールで解消できる。resizeは、僕使っているサーバのOS:Debian lennyではxtermパッケージに含まれている。ディストリビューションによってはxutilsパッケージに含まれていることもあるようだ。

ssh等でサーバに接続後、resizeコマンドを打てば、自分の開いているローカルのコンソールの解像度(行数)に、リモートのコンソールの解像度(行数)をあわせてくれる。

これまでサーバ側で大した用事をしなかったので、解像度(行数)がちぐはぐでも我慢できたが、用事が増えてきたので調査した。調査時はスタンドアローンなマシンでのコンソール解像度についての話題が多く、多少手こずった。liloの引数でvga=xxxを渡すっていう話です。

なお、調査では下記の記事を参考にした。
DSAS開発者の部屋:UML のコンソールを screen に表示させる 〜疑似端末を screen に結びつける

http://dsas.blog.klab.org/archives/50992202.html

launchdで毎日同じ時刻にブログ投稿画面を表示させるようにした。

日曜日, 7月 19th, 2009

先の投稿で,日々一定時刻に投稿画面が表示されれば,日々のチェックポイントとしてブログを書くようになるのではないか,と考えた.そこで,OSXとFirefoxを使って,ある時刻にブログの投稿画面が表示されるようにした.

OSXで,ある時刻にアプリケーションを起動させる方法は2種類ある.

  • iCalのアラーム機能を利用する
  • OSXのプロセスを管理しているlaunchdを利用する

今回はlaunchdを利用する.その理由は,iCalのアラーム機能では特定のアプリケーション(FirefoxやSafari)をある時刻に起動することはできるが,そのアプリケーションで開くページやコンテンツを指定できない.正確には,ある時刻にapplescriptを起動させることが可能なので,applescriptの中でfirefoxを起動し,firefoxに対してあるURLを開かせる処理をさせられる.しかし,私の環境(Firefox 3.5 + OSX Leopard)では動作しなかった.

launchdは,UNIXでいうinitプロセスと同等である.UNIXではシステム起動時にinitプロセスを起動し,そのプロセスが各種デーモンの起動終了の面倒を見る.OSXではinitプロセスの代替として,launchdが用意されている.

今回の目的は,ある時刻にFirefoxを起動し,ブログ投稿ページを表示させることだ.そのため,まずFirefoxを起動し,ブログ投稿ページを表示させるスクリプトを用意する.次に,そのスクリプトをある時刻に起動するようlaunchdに設定する.

Firefoxをコマンドから起動させる場合は,Firefox以下Contents/MacOS/firefox-binを叩く.用意したスクリプトは以下.このスクリプトを,/Users/ryan5500/bin/invoke_firefox.shに配置した.一応chmod 755して起動可能な状態にしておく.

[shell]
#!/bin/sh
/Application/Firefox/Contents/MacOS/firefox-bin "http://www.ryan5500.com/post-new/"
[/shell]

次に,launchdに上記スクリプトを起動させるための設定を書く.用意した設定ファイルは以下.これを,~/Library/LaunchAgents/com.ryan5500.blog.checkpoint.startup.plistに配置した.LaunchAgentsというのは,Launchdが起動するがデーモンではなく,各ユーザーのために起動するものだ.すなわち,ryan5500ユーザーがログインしたときしか,下記のスクリプトは有効にならない,ということだ.

[xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.ryan5500.blog.checkpoint.startup</string>
<key>Program</key>
<string>/Users/ryan5500/bin/invoke_firefox.sh</string>
<key>ProgramArguments</key>
<array>
<string></string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>18</integer>
<key>Minute</key>
<integer>10</integer>
</dict>
</dict>
</plist>
[/xml]

この設定ファイルでは,用意したスクリプトを毎日18時10分に起動する.

この設定ファイルを~/Library/LaunchAgents以下に配置したからといって,設定は有効にならない.設定ファイルをlaunchdに読み込ませる処理が必要である.読み込ませるには,以下のコマンドを叩く.

[shell]
$launchctl load ~/Library/LaunchAgents/com.ryan5500.blog.checkpoint.startup.plist
[/shell]

きちんと読み込まれたか確認したい人は,以下のコマンドでcom.ryan5500.blog.checkpoint.startupが表示されるか見れば良い.

[shell]
$launchctl list
[/shell]

以上.これで毎日ブログ投稿画面が表示される環境が整った.ちゃんとブログを書くようになるだろうか.

参考にしたURLを以下に残す.
OSX 10.5 Leopardでcronを使う – 偏った言語信者の垂れ流し

http://d.hatena.ne.jp/nullpobug/20080611/1213196369

Undocumented Mac OS X:第1回 initを置き換えるlaunchd【前編】 (1/3) – ITmedia エンタープライズ

http://www.itmedia.co.jp/enterprise/articles/0704/26/news009.html

LaunchDaemons (launchctl, launchd.plist) の使い方 – maruko2 Note.

http://www.maruko2.com/mw/LaunchDaemons_%28launchctl,_launchd.plist%29_%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9

Perlプログラムの最後の1;について

木曜日, 7月 9th, 2009

Perlのプログラムを読んでいると,最後に1;として終わっているプログラムがあることに気づく.これは何だろう,と思いながらCatalystのマニュアルを読んでいたら,その答えが書かれていた.
Note: Be careful to put this code above the 1; at the end of the file. As with any Perl package, we need to end the last line with a statement that evaluates to true. This is customarily done with 1; on a line by itself.

そうだったんだ.

OSX(Leopard)にwebフレームワークArkをインストールした

日曜日, 6月 21st, 2009
photo by cogdogblog

photo by cogdogblog

MacBook white /w OSX Leopardに,Perlのwebフレームワーク「Ark」をインストールした.
その経過を残す.ただし,僕はPerl初心者なので,「いや,違うやろ」って場所はコメントにて指摘をお願いします.

とにもかくにも,まずはArkをダウンロード.
[shell]
$ wget http://cloud.github.com/downloads/typester/ark-perl/Ark-0.001000_001.tar.gz
$ tar zxvf Ark-0.01.tar.gz
[/shell]

で,次にテストなのだが,その際に必要なCPANモジュールがインストールされていないため,足止めを喰った.僕がつまづいたのは,Mac::Carbon,File::Find::Rule,DBD::mysql,DBIx::Class::Schema::Loaderだ.

まずMac::Carbonから.これはCPANからインストールするのではなく,portから入れた.
[shell]
$sudo port install p5-mac-carbon
$sudo port install p5-mac-appleevents-simple
[/shell]
p5-mac-appleevents-simpleは必要かわからない.下記のブログを参考にした.

http://d.hatena.ne.jp/jazzanova/20090520/1242755894

次にFile::Find::Rule.以下の様なエラーが出た.

CPAN.pm: Going to build R/RC/RCLAMP/File-Find-Rule-0.30.tar.gz

Too early to specify a build action ‘y’. Do ‘Build y’ instead.
Warning: No success on command[/opt/local/bin/perl Build.PL y]
RCLAMP/File-Find-Rule-0.30.tar.gz
/opt/local/bin/perl Build.PL y — NOT OK
Running Build test
Make had some problems, won’t test
Running Build install
Make had some problems, won’t install

なので,手動でインストールする.インストール方法はREADMEに書いてあった.
[shell]
cpan> look File::Find::Rule
bash-3.2# perl Build.PL
bash-3.2# perl Build test
bash-3.2# perl Build install
[/shell]

DBD::mysqlでは,テスト時にtestというデータベースを利用するらしいので,用意してあげた.
[shell]
$mysql -u root -p
mysql> create database test;
[/shell]

僕の設定では,mysqlのソケットは,/opt/local/var/run/mysql5/mysqld.sockに用意されるが,DBD::mysqlのテストでは/tmp/mysql.sockにソケットがあると考えてテストをする.なので,/opt/local/var/run/mysql5/mysqld.sockのシンボリックリンクを/tmp/mysql.sockに用意した.

[shell]
$ln -s /opt/local/var/run/mysql5/mysqld.sock /tmp/mysql.sock
[/shell]

DBIx::Class::Schema::Loaderもちゃんと入らなかったので,lookして手動でmake.
[shell]
cpan> look DBIx::Class::Schema::Loader
bash-3.2# perl Makefile.PL
bash-3.2# make test
bash-3.2# make
bash-3.2# make install
[/shell]

これで依存モジュールは解決.あとはマニュアル通りです.
[shell]
$cd Ark-xxxxxx
$sudo cpan -t .
$sudo cpan -i .
[/shell]

とりあえずOpenID系は無視して,インストール完了しました.

「初めてのPerl第3版」(リャマ本)読書ログ – 第17章「上級テクニック」

土曜日, 6月 20th, 2009

初めてのPerl

0による除算エラーや不正な正規表現は,プログラムをクラッシュさせる可能性がある.それら致命的なーエラーをキャッチするには,コードをevalでくくればよい.

[perl]
my $dino = 0;
eval {
$barney = $fred / $dino;
};
[/perl]

evalはwhileなどの制御構造ではなく式なので,evalの後ろにはセミコロンが必要になる.
eval内で実行されたコードが不正終了したのかどうかを調べるには,特殊変数$@が用いられる.evalが致命的なエラーをキャッチした場合,$@にメッセージがセットされる.$@が空なら,eval内のコードは正しく実行されたと考えてよい.

evalブロックの中に,他のevalブロックをネストすることもできる.内側のevalブロックでエラーをトラップすると,外側のevalブロックではエラーをトラップしない.エラーを伝播させるには,dieを使えばよい.

evalが致命的なエラーをトラップした場合,その戻り値はundefか空リストになる.そのため,上記の例では,$barneyの値がundefかどうかを調べれば致命的なエラーが起こったかどうかを知ることができるため,$@を見ることで致命的なエラーが起こったかどうかを調べる必要はない.

evalでトラップできないエラーは4種類ある.1)Perlそのものをクラッシュさせるエラー(メモリ不足,シグナル等),2)evalブロック内で発生した構文エラー(コンパイル時にキャッチされる),3)exit演算子(プログラムを終了させる),4)警告(ユーザーがwarnによって発生させた警告)からなる4つである.

リストから一部の要素だけ取り出したい,ということがよくある.リストの中から,奇数だけを取り出したい,Fredという名前が入ったものだけ取り出したい,等である.grep演算子でそれらは可能だ.

[perl]
my @odd_numbers = grep { $_ % 2} 1..1000;
#1から1000までの間で,奇数のもののみodd_numbersにpush
[/perl]

ブロックを引数に取り,そのブロック内の操作で値を返したものがリストに入る.

[perl]
my @matchin_lines = grep { /\bfred\b/i } <FILE>;
my @matchin_lines = grep /\bfred\b/i , <FILE>; #さらにシンプルに書ける!
[/perl]

数値リストを金額として一時的に表示する場合,mapを使ってリストを変換できる.
[perl]
my @data = {4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95};
my @formatted_data;

foreach (@data) {#この処理がmapを使うことで短縮できる
push @formatted_data, &big_money($_);
}

my @formatted_data = map{ &big_money($_) } @data;
[/perl]

map演算子は,引数の内容を$_にマップし,ブロックに渡す.

次に,ハッシュのショートカットを紹介する.ハッシュのキーを書く際は,クォートを省略できる.キーが英文字と数字と下線だけから成り,先頭が数字以外のものであれば,クォートを省略できる.このようなキーのことを裸のワード(bareword)という.

[perl]
my %score = (
barney => 195,
fred => 205,
dino => 30,
);
[/perl]

次は正規表現のコツについてだ.通常の量指定子(+や*等)は,欲張りなマッチを行う.すなわち,パターン/fred.+barney/と文字列”fred and barney went bowling last night”が合ったときに,パターンはfredとマッチしたあと,.をマッチさせる為にnightのtからじょじょにバックトラックする形でマッチの試行を行う.barneyまでマッチ試行がバックトラックしたときに初めて結果を返す.
しかしこのような欲張り型のマッチだと,あるHTML文書からタグだけ抜き出すような場合や,文章が長い場合には適さない.そこで,欲張りでないマッチを行いたい場合には,量指定子に?を付けよう.

[perl]
$str = "<html>hogehoge<bold>fuga</bold>. hogefuga<bold>hoge</bold>.</html>";
if($str =~ /<bold>(.*)<\/bold>/) {#欲張りな量指定子の時
print $1; #fuga</bold>.hogefuga<bold>hogeが出力される.
}

if($str =~ /<bold>(.*?)<\/bold>/) {#欲張りでない量指定子の時
print $1; #fugaが出力される.
}
[/perl]

また,複数行のテキストに対するマッチを行うこともできる.そのためには/mオプションを指定すれば良い.

[perl]
$_ = "I’m much better\nthan Barney is\n at bowling, \nWilma.\n";#4行のテキスト
print "found ‘wilma’ at start of line\n" if /^wilma\b/im;
[/perl]

リストはリストスライスという機能によって,その要素のいくつかだけを簡単に取り出すことができる.
例えば,以下のように.

[perl]
$_ = "1:tomoaki sano:24";
my $sano_old = (split /:/)[2];

my @names = qw/ zero one two three four five six seven eight nine /;
my @numbers = @names[9, 0, 2, 1, 0];#配列もスライスできる

my %scores = {fred => 68, dino => 110};
my @two_scores = @scores {qw/ fred dino /};#ハッシュもスライスできる
[/perl]

「初めてのPerl第3版」(リャマ本)読書ログ – 第16章「単純なデータベース」

金曜日, 6月 19th, 2009

初めてのPerl

perlはシンプルなデータベースであるDBMがデフォルトで利用できる.DBMのデータベースは,my_database.dirとmy_database.pagという2つのファイルからなる.DBMの利点は,perlプログラム上でハッシュと同じようにDBのコンテンツを扱えることにある.

[perl]
dbmopen(%DATA, "my_database", 0644) #my_databaseというDBMをオープンする
or die "Cannot create my_database: $!";

$DATA{"fred"} = "bedrock"; #DBMへのデータ追加
$DATA{"barney"} = "hoge";
remove $DATA{"barney"}; #DBMからのデータ削除

foreach my $key (keys %DATA) {
print "$key\n";
}
[/perl]

なお,データ数が増えるほど,keysを使ってハッシュのキーリストを得る処理は重くなる可能性がある.keysはハッシュ全体をスキャンするので,大きなリストを生成するかもしれないから.DBMハッシュをスキャンするときは,一般には,each関数を使った方がメモリの使用量が少なくて済む.

[perl]
while( my($key, $value) = each(%DATA)) {
print "$key has value of $value\n";
}
[/perl]

データをDBMに格納する際,1つのキーに対して複数の値を格納したいときは,pack/unpack関数を利用する.packは,フォーマット文字列と引数のリストを受け取って,それらをもとに1個の文字列を生成する.

[perl]
my $buffer = pack("c s l", 31, 4159, 263539);
my($char, $short, $long) = unpack("c s l", $buffer);#charには31, shortには4159, longには263539が入る
[/perl]

DBMはいうなれば巨大なハッシュだったが,他にも固定長や可変長のテーブルを利用することができる.固定長テーブルと可変長テーブルについての解説は必要になれば追記する.

perlはちょっとした処理を行う為に,一行のプログラムをさくっと実行するモードを用意している.

[perl]
$perl -p -i.bak – w -e ’s/Rnadall/Randal/g’ fred*.dat
[/perl]

-pオプションは以下のようなプログラムを追加する処理をする.

[perl]
while(<>) {print;}
[/perl]
-eオプションで指定されるのが,実行して欲しいプログラムとなる.これが,上のwhile(<>)内に入ると考えれば良い.-i.bakオプションは,実行前に$^Iに.bakをセットする.これはすなわち,ダイアモンド演算子で指定されたファイルのバックアップファイルの拡張子として,.bakを利用する,というものである.-wオプションは,先に述べた通り,警告を出させる.-eオプションの次に来るfred*.datがプログラムに対する引数となる.

「初めてのPerl第3版」(リャマ本)読書ログ – 第15章「文字列処理とソート」

木曜日, 6月 18th, 2009

初めてのPerl

index関数を使うと,ある文字列の部分文字列を検索できる.返り値は部分文字列が出現する場所の位置インデックスを返す.インデックスは0から始まる.つまり,文字列「hogefuga」の中で「ho」という部分文字列を探すと,indexは0を返す.部分文字列が見つからなければ-1を返す.また,indexは常に最初に見つかった部分のインデックスを返す.

[perl]
$where = index($str, $small);
#$strの中から$smallにマッチする位置インデックスを返す
[/perl]

常に最後に見つかった部分文字列のインデックスがほしければ,rindex関数をindex関数と同様に呼び出せば良い.

substrは他の言語と同じように,部分文字列を取得できる.3つの引数を取り,対象とする文字列,取得する開始位置インデックス,取得する終了位置インデックスを渡す.
さらに,第1引数の文字列が変数なら,その変数のうち,指定した部分のみ書き換えることができる.

[perl]
my $mineral = substr("Fred J. Flintstone", 8, 5); # Flintを返す
my $rock = substr "Fred J. Flintstone", 13, 1000; #stoneを返す(末尾を超える指定の場合,最後まで返す)
my $pebble = substr "Fred J. Flintstone", 13; #stoneを返す(末尾の指定がない場合,最後まで返す)

my $string = "Hello, world!";
substr($string, 0, 5) = "Goodbye"; #$stringにはGoodbye, world!となる
[/perl]

C言語にあるsprintfも,同じように利用できる.

次に,ソートサブルーチンについて説明する.すでに,リストやハッシュをソートする関数sortについて述べた.しかしリストの内容によってソートする方法は違う.そこで,ソートサブルーチンを利用することで,自分の望むようにリストをソートできるようになる.
ソートサブルーチンは,通常のルーチンのように宣言するが,引数として$a, $bが規定される.具体的には以下のように書く.

[perl]
sub by_number {
if($a < $b) {-1 } elsif ($a > $b) {1} else {0}
}
[/perl]

ソートサブルーチンをツアクには,キーワードsortとソートすべきリストの間にその関数を置く.以下のように.

[perl]
my @result = sort by_number @some_numbers;
my @result = sort {$a <=> $b } @some_numbers; #通常はこっち
[/perl]

ソートサブルーチンの中では$aと$bを宣言したり,値をセットしたりする必要はないことに注意せよ.上記のby_number関数の処理はよくあることなので,スペースシップ演算子(<=>)を使うことで同様の機能を実装できる.しかし,スペースシップ演算子は数値のみに有効である.文字列に対しては,cmp関数を利用する.
実際はソートサブルーチンを書くことはまれで,2個目の例のように関数をインラインで書く.

数値を降順(大きいものから小さいものの順)でソートする場合,$aと$bを逆にするだけでよい.

ハッシュを値によってソートする場合は以下のように書く.

[perl]
my %score = ("barney => 195, "fred" => 205, "dino" => 30);
sub by_score {$score{$b} <=> $score{$a}}
[/perl]

「初めてのPerl第3版」(リャマ本)読書ログ – 第14章「プロセス管理」

木曜日, 6月 18th, 2009

初めてのPerl

Perlで子プロセスを起動する方法の一つにsystem関数を利用することがある.
[perl]
system "date"; #unixのdateコマンドを呼び出す
[/perl]

system関数は,Perlの標準入力,標準出力,標準エラーをそのまま受け継ぐ.上の例では,dateコマンドの結果をPerlのSTDOUTと同じところに送られる.
また,Perlはsystemで起動した子プロセスが終了するまで次の式の実行を待つ.すなわち,dateコマンドの実行に10秒かかるとしたら,10秒間は次の式を実行しない.ここのことから,systemで起動するコマンドが,対話側のものだった場合に問題が起こる.例えば,dateコマンドが単純に時刻を返すコマンドではなく,起動時に「どの地域の時刻を返しますか?」と聞き,入力を促すコマンドだった場合,入力を渡すまでこのPerlスクリプトは終了しない.しかし,system関数の時点でdateコマンドの終了を待つため,永遠にPerlスクリプトが終わらないことが起こりえる.
シェルのバックグランドプロセスを起動することで,この動作を回避できる.

system関数の中で,Bourneシェル(/bin/sh)を起動し,シェルスクリプトの実行も可能である.

[perl]
system ‘for i in *.pl; do echo == $i ==; cat $i; done’; #.plファイルの中身を出力する
[/perl]
シングルクォートを使うのは,$記号をPerlスクリプト内の変数と混同しないため.

2個以上の引数を渡して,system演算子の起動も可能だが,その場合はシェルは起動できない.

[perl]
my $tarfile = "something*wicked.tar";
my @dirs = qw(fred|flintstone <barney&rubble> betty );
system "tar", "cvf", $tarfile, @dirs; #きっかり5つの引数がtarコマンドに渡される.
[/perl]

systemに渡される引数は,第1引数がコマンド名で,それ以降の引数はコマンドに渡される引数となる.上の例では,tarコマンドに,”cvf”, $tarfile, “fred|flintsone”, ““, “betty”の5つの引数が渡される.

上の例に比して,以下の例は危険である.絶対に真似せぬよう.
flintstoneコマンドに大量のデータを流し込む動作をすることになる.

[perl]
system "tar cvf $tarfile @dirs";
[/perl]

なお,system関数は,成功すればUNIXでの成功をあらわす0を返す.0以外の終了値は何かがうまくいっていないことを示す.

system関数と似た動作をする関数としてexecがある.違いは,execからコマンドを実行した場合,それはPerlの子プロセスとならず,Perlのプロセスを終え,そのコマンドを実行するプロセスのみが残ることになる.exec関数は,他のプログラム実行するための環境を用意する際に活きる.

system関数を使う場合,気になるのが環境変数PATHだろう.Perlでは環境変数は以下のようにして設定する.

[perl]
$ENV{‘PATH’} = "/home/rootbeer/bin:$ENV{‘PATH’}"; #環境変数PATHへの追加
delete $ENV{‘IFS’}; #環境変数IFSの削除
[/perl]

system関数呼び出したコマンドの出力は,標準出力に送られることは既に書いた.しかし,コマンドの出力を取得して変数に格納するのに,もっと簡単な方法もある.逆クォートを利用することである.

[perl]
my $now = `date`; #dateコマンドの実行結果をnow変数に格納する
[/perl]

しかし,出力を取り込まないときは,逆クォートを利用するべきでない.出力をperlが拾っているのに,せっせと捨てることになるし,意図がわからなくなるためだ.

リストコンテキストで逆クォートを利用すると,結果を行毎に分割して格納する.

これまではPerlから子プロセスを生成し,子プロセスの処理が終了するまで待つ,という同期プロセスを扱ってきた.しかし,Perlとの通信を行いつつ,処理が完了するまで独立して実行される子プロセスもPerlは扱える.それには,open関数を利用する.open関数は並列実行するプロセスをファイルハンドルとして扱う.また,並列実行するコマンドの真絵馬は後ろに縦棒を付けたものを指定する.

[perl]
open DATE, "date|" or die "cannot pipe form date: $!";
open MAIL, "|mail merlyn" or die "cannot pipe to mail: $!";
[/perl]

縦棒がコマンドの右についているもの(date|)では,コマンドの標準出力が,入力用にオープンされたDATEファイルハンドルに連結される. 逆に縦棒がコマンドの左についているもの(|mail)では,コマンドの標準入力が,出力用にオープンしたMAILファイルハンドルに連結される.

データの入力,出力されたデータの取得は通常のファイルハンドルと同様に行う.

perlからUnixのシグナルの送信が可能である.シグナルは名前(SIGINT割り込みシグナル)とそれに対応する小さな整数値によって識別される.例えば,端末からコントロールC等の割り込み入力を行うと,プロセスにSIGINTシグナルが送られる.

Perlスクリプトからシグナルを送るには,シグナルの種類と,プロセスのIDが必要になる.
プロセス番号4211のプロセスにシグナルを送るには,kill関数を利用する.

[perl]
kill 2, 4211 or die "cannnot signal 4211 with SIGINT: $!";
[/perl]

killの第1引数はシグナルの種類を表す.2はSIGINTを送る.

「初めてのPerl第3版」(リャマ本)読書ログ – 第13章「ファイルとディレクトリの取り扱い」

木曜日, 6月 18th, 2009

初めてのPerl

perlスクリプトからファイルを削除するにはunlink演算子を使う.ディレクトリは削除できない.

[perl]
unlink "slate", "bedrock", "lava.pl"; #slate, bedrock, lava.plというファイルを削除する
[/perl]

unlinkは引数にリストを取るので,globを使って複数のファイルを削除できる.

[perl]
unlink glob "*.o";
[/perl]

unlinkは削除に成功したファイルの個数を返す.

[perl]
$remove_num = unlink glob "*.o";
print "removed file num : $remove_num\n";
[/perl]

ただし,この場合,1や2が返ってくると,どのファイルが削除されたかわからない.その場合は,ファイルリストをforeachで回し,一つずつ削除するべきだ.この場合,unlinkが返すのは,1か0の値となり,bool値として扱える.

また,unlinkが失敗した場合,$!にオペレーティングシステムエラーに関するメッセージが入る.デバッグの際は$!を利用すると良い,

ファイル名の変更には,rename演算子を使う.

[perl]
rename "old", "new"; #oldという名前のファイルをnewという名前に置き換える
[/perl]

renameが失敗すると返り値として偽を返し,$!にオペレーティングシステムエラーに関するメッセージが入る.

次はハードリンクをperlスクリプトで貼る方法だ.link演算子を使うことで実現できる.renameと同じく,失敗すると偽を返し,$!にエラーメッセージを返す.

[perl]
link "hoge" "fuga"; #hogeへのリンクであるfugaを生成する
[/perl]

シンボリックリンクを貼るには,symlink関数を使う.逆にシンボリックリングが指している場所を知るには,readlink関数を使う.

[perl]
symlink "dodgson", "carroll";
my $where = readlikn "carroll"; #dodgsonが得られる.
[/perl]

ディレクトリの作成はmkdir関数を使う.引数はファイル名とパーミッションの2つだ.

[perl]
my $name = "fred";
my $permissions = "0755";
mkdir $name, oct($permissions); #oct関数は文字列を強制的に8進数と見なす
[/perl]

ディレクトリの削除はrmdirだ.また,パーミッションの変更はchmod関数を利用する.オーナーの変更はchown関数を利用する.これはunixのchmodと同じ構文で利用できるので解説しない.

現在の時刻の取得はtime関数を引数無しで呼び出すことで実現される.また,ファイルのタイムスタンプを変更するには,utime関数を利用する.

[perl]
my $now = time;
my $ago = $now – 24 * 60 * 60;
utime $now, $ago, glob "*"; #カレントディレクトリのファイル群のタイムスタンプを変更
[/perl]

ファイルパスからベース名を取得するには,File::Basenameモジュールを使う.

[perl]
use File::Basename;
my $name = "/usr/local/bin/perl";
my $basename = basename $name; # ‘perl’となる
[/perl]

File::Basenameモジュールの中には複数の関数が含まれている.use宣言を使って関数をスクリプトに読み込ませる際に,”インポートリスト”を利用することで,どの関数を読み込むか指定することができる.

[perl]
use File::Basename qw / basename /; #basename関数のみ読み込ませる
[/perl]