« 2004年02月 | メイン | 2004年04月 »

2004年03月20日

use utf8;

perl のスクリプト内で日本語を記述したいなら、Perl 5.8 以降の場合、文字コードは UTF-8 を使うのが簡単なようだ。正規表現もきちんと使えるし、「表」など Shift JIS では注意が必要だった文字も普通に扱うことができる。

use utf8;
と書いておけばソース内部の非アスキー文字は UTF-8 として解釈される。モジュールの場合は、
noencoding;
use utf8;
と書く。

この utf8 プラグマは、ソースが UTF-8 で記述されていることを示すだけで、外部のファイルから日本語を読んだり、日本語を書き出したりするときの挙動には関係がないようだ。

投稿者 augustus : 22:57 | コメント (0) | トラックバック

Encode, Encode::Guess モジュール

Encode モジュールを使うと、いろいろな文字コードを decode できる。どういう文字コードであるかをスクリプトに決定させるには、 Encode::Guess モジュールを使う。Active Perl のヘルプには以下のような例が載っている。$data に入っている文字列の文字コードを判別して、decode するものだ。
use Encode::Guess,
my $enc = guess_encoding($data, 
      qw/euc-jp shiftjis 7bit-jis/);
ref($enc) or die "Can't guess: $enc";
$utf8 = $enc->decode($data);
# or
$utf8 = decode($enc->name, $data)

投稿者 augustus : 22:48 | コメント (0) | トラックバック

2004年03月14日

Linux から Windows への perl スクリプトの移植

Linux で動作するように書かれた Perl のスクリプトの中には OSの機能の違いから Windows 上では動作しないものも多い。
ActivePerl の開発元の ActiveState 社のサイトには "Implementation Quirks" という記事があり、実装されていない関数として、以下のようなものが挙げられている。これらの関数を使っているものはそのままでは動かないだろう。

プロセス関係
alarm(), getpgrp(), getppid(), getpriority(), setpgrp(), setpriority()

ユーザやグループに関するもの
endgrent(), endpwent(), getgrent(), getgrgid(), getgrnam(), getpwent(), getpwnam(), getpwuid(), setgrent(), setpwent()

System V IPC 関係
msgctl(), msgget(), msgrcv(), msgsnd(), semctl(), semget(), semop(), shmctl(), shmget(), shmread(), shmwrite()

ファイルやディレクトリに関するもの
link(), symlink(), chroot()

入出力に関するもの
syscall()

ネットワーク関係
getnetbyname(), getnetbyaddr(), getnetent(), getprotoent(), getservent(), sethostent(), setnetent(), setprotoent(), setservent(), endhostent(), endnetent(), endprotoent(), endservent(), socketpair()


Microsoft TechNet にも「Linux から Windows 2000 へのスクリプトの移植性」という記事があり、参考になる。

投稿者 augustus : 11:00 | コメント (0) | トラックバック

2004年03月08日

Perl から DBI 経由でデータベースを使う

perl から Access や SQL Server のデータベースを扱うのに、OLE経由でADOを使う他、DBIを使うこともできる。 DBI経由はデータベースを変更しても接続文字列を変えるくらいで対応が出来きて便利だと思われる。

下の例の接続文字列は SQL server または MSDE のものだが、アクセスで hoge.mdb に接続するなら
dbi:ODBC:driver=Microsoft Access Driver (*.mdb);dbq=hoge.mdb という接続文字列を使えば良い。
use DBI;

# 接続文字列(SQL Server or MSDE の例)
$dataSource = "dbi:ODBC:".
    "driver={SQL Server};".
    "Server=(local);database=test;".
    "Trusted_Connection=yes;". # yesだとWindows認証
    "AutoTranslate=No;";
    
#データベースに接続
$user="tuser"; #ユーザ名
$pwd="tuser";  #パスワード
$dbh=DBI->connect($dataSource,$user,$pwd)
    or die $DBI::errstr;

# テーブル削除
$dbh->do("Drop table seito");

# テーブル作成
$dbh->do(
    "Create Table seito(id int, name varchar(30))"
) or die $DBI::errstr;

# データ挿入
$sth = $dbh->prepare(
    "INSERT INTO seito (id,name) VALUES (?,?)");
$sth->execute(11, "菅原 道真");
$sth->execute(12, "藤原 道長");

# データ読み出し
$ref=$dbh->selectall_arrayref("select * from seito");
for $x (@{$ref}){
	print join("/", @{$x},"\n");
}

# データベースから切断
$dbh->disconnect;


データベースを新規作成することは出来ないのかなあ?

投稿者 augustus : 19:53 | コメント (1) | トラックバック

2004年03月07日

SQLserver に perl でアクセス

この間のアクセスのデータベースを使った例と基本的に同じでよいのだが、接続文字列の書き方を忘れたときのためにメモを残しておく。

接続文字列中で Data Source= のあとにはサーバ名を書く。ローカルのSQL server または MSDE を使うなら Data Source=(local) と書ける。
Initial Catalog= のあとにはデータベース名を書く。

ユーザ名、パスワードは user id=, password=で指定する。もし、Windows認証を使うのなら、ユーザ名とパスワードの指定の替わりに、
Integrated Security=SSPI
あるいは
Trusted_Connection=yes
と書けばよい。
# SQLserver のデータベース操作の例
#
#     SRV2003 という名のサーバ上の SQLserver の
#     test という名のデータベースに接続し、
#     seito というテーブルを作成し、データを追加し、
#     データを読み出す。

use Win32::OLE;
$server="SRV2003";
$db="test";
$user="tuser";
$password="tuser";

# データベースへの接続
$objDB=Win32::OLE->new("ADODB.Connection");
$connStr="Provider=sqloledb;".
	"Data Source=${server};".
	"Initial Catalog=${db};".
	"user id=${user};password=${password}";
$objDB->Open($connStr);
$objDB->{Errors}->{Count} and 
    die "cannot connect '$connStr'";

# テーブル作成
$objDB->Execute(
    "Create Table seito (id int, name Char(20))" );

# データ挿入
$objDB->Execute(
    "Insert into seito values (11,'蘇我 馬子')");
$objDB->Execute(
    "Insert into seito values (12,'中臣 鎌子')");

# データ読み出し
$rs=Win32::OLE->new("ADODB.Recordset");
$rs->Open("select * from seito", $objDB);
while(!$rs->EOF and $rs->{RecordCount}!=0){
    print "$rs->{Fields}->{id}->{Value}, ",
        "$rs->{Fields}->{name}->{Value}\n";
    $rs->MoveNext();
}
$rs->Close();

# 接続を閉じる
$objDB->Close();
$objDB=undef();

投稿者 augustus : 11:58 | コメント (2) | トラックバック

2004年03月06日

スタートアップスクリプトではUNC名が使えない

Windows 2000 や XP では、起動時に実行させるスタートアップスクリプトというのが使えるが、その中ではファイル名の指定にUNC名(\\server1\aaa\bbb\xxx.txt みたいな表現)が使えない。

なぜいまさら気がついたかと言うと、クライアントPCの情報をスタートアップスクリプトを使ってサーバに集めようと考えたのだが、標準出力をサーバ上のファイルにリダイレクトしようとして見事にはまってしまったのだった。スタートアップスクリプト中でリモートのファイルにアクセスしたいとき、世のシステム管理者の皆さんはどうしているのだろうかと疑問に思った。(クライアントPCのローカルのファイルを使うしかないのだろうか。)

もっと詳しく状況を書くと、各PCの ipconfig /all の出力結果を集めたいと考えており、そのためにスタートアップスクリプトを使い標準出力をサーバ上のファイルにリダイレクトしたかったのだ。
現在考えている解決策は
1)クライアントPCのローカルドライブに出力を保存させておき、適当なときに Wake up on LAN を使って電源を入れてやってから、サーバに当該ファイルを集めてくる。
2)Windows XP からのコマンドラインツールである eventcreate を使いサーバのイベントログに必要な情報を書き込ませる。
3)スタートアップスクリプトのかわりにログオンスクリプトを使う。

投稿者 augustus : 21:11 | コメント (0) | トラックバック