NTシステムデザインの技術メモ

DOS形式ftpサーバーから自動ファイル取得

最終更新:

ntaka206

- view
管理者のみ編集可
白山工業製LS-7000のftpサーバーは、lsコマンドで得られるファイルリストの形式が一般的なUNIX形式ではなくDOS形式である。cd コマンドに与えるパスの区切り文字も”\”である。このせいで、lftpなどのミラーリング機能を使ってデータ取得が出来ない。このftpサーバーに対応した、ftpミラーリングget用perlスクリプトを作った。

LS7000のftpサーバー
08-12-10  09:33AM                  896 SET1.CNF
08-12-10  02:59PM                  896 SET2.CNF
08-24-10  11:51AM                43712 TCAL.TXT
08-16-10  00:01AM       <DIR>          100816
08-17-10  00:01AM       <DIR>          100817
08-18-10  00:01AM       <DIR>          100818
一般的なunixのftpサーバー
-rw-r--r--  1 ntaka ntaka    56785 Aug  2 11:14 hs_err_pid2384.log
-rw-r--r--  1 ntaka ntaka    42748 Jul 30 18:56 hs_err_pid2658.log
-rw-r--r--  1 ntaka ntaka    60322 Jul 30 13:35 hs_err_pid2978.log
今回はftpによるミラーリングをするために、CAPNからNet::DownloadMirrorNet::MirrorDirモジュールを取得して使用している。Net::MirrorDir->ReadRemoteDir()の書き換えで、LS7000のDOS形式ファイル一覧に対応させている。

●ftpデータミラーリング取得プログラム
mirror_wp.pl perlプログラム本体 このページ最下部からダウンロード可
DownloadMirror.pm ftpミラーリングモジュール CPANからgetしてmirror_wp.plと同じフォルダに保存
MirrorDir.pm ftpミラーリングモジュール CPANからgetしてmirror_wp.plと同じフォルダに保存 一部変更

複数台のLS-7000からデータ取得できるようになっている。前日1日分のデータを取得する。
ローカル側のファイルは、リモート側で無くなっても削除されない。
プログラムソースを書き換えれば、全てのデータを取得させることも出来る。$all = 1;にする。

●MirrorDir.pmの修正箇所
sub ReadRemoteDir
	{
	my ($self, $dir) = @_;
	$dir ||= $self->{_remotedir};
	return({}, {}) unless(eval { $Net::MirrorDir::_connection->cwd($dir); });
# LS7000にて CWD / するとinvalid argumentになるため
# 	return({}, {}) unless($Net::MirrorDir::_connection->cwd());
	$self->{_remotefiles} = {};
	$self->{_remotedirs} = {};
	$self->{_readremotedir} = sub 
		{
		my ($self, $p) = @_;
		my (@info, $name, $np, $ra_lines);
		my $count = 0;
		until($ra_lines = $Net::MirrorDir::_connection->dir($p) || ++$count > 3)
			{
		$self->Connect() unless($Net::MirrorDir::_connection->abort());
			}
		if($self->{_debug})
			{
			print("\nreturnvalues from <dir($p)>\n");
			print("$_\n") for(@{$ra_lines});
			}
		for my $line (@{$ra_lines})
			{
		@info = split(/\s+/, $line);
			$name = $info[$#info];
			next if($name eq '.' || $name eq '..');
			$np = "$p/$name";
		next if(grep { $np =~ $_ } @{$self->{_regex_exclusions}});
# LS7000 DOS形式ftp対応
			if($line =~ m/<DIR>/) {
				$self->{_remotedirs}{$np} = 1;
				$self->{_readremotedir}->($self, $np);
			} else {
				$self->{_remotefiles}{$np} = 1
					unless(@{$self->{_regex_subset}});
				for(@{$self->{_regex_subset}}) {
					if($np =~ $_) {
						$self->{_remotefiles}{$np} = 1;
						last;
					}
				}
			}
			} # for
# 			if($line =~ m/^-/)
# 				{
# 				$self->{_remotefiles}{$np} = 1
# 					unless(@{$self->{_regex_subset}});
# 				for(@{$self->{_regex_subset}})
# 					{
# 					if($np =~ $_)
# 						{
# 						$self->{_remotefiles}{$np} = 1;
# 						last;
# 						}
# 					}
# 				}
# 			elsif($line =~ m/^d/)
# 				$self->{_remotedirs}{$np} = 1;
# 				$self->{_readremotedir}->($self, $np);
# 				}
# 			else
# 				{
# 				warn("error can not get info: $line\n");
# 				}
#			}
	return($self->{_remotefiles}, $self->{_remotedirs});
		};
	return $self->{_readremotedir}->($self, $dir);
	}
●CPANからgetしたモジュールの場所を調べるには?
$ perldoc -ml Net::MirrorDir
/usr/local/share/perl/5.10.1/Net/MirrorDir.pm
添付ファイル
ウィキ募集バナー