perl文件如下,继续上一个问题
#! /usr/bin/perl
################################################################################
# 名 称:transfer.pl
# 業 務:汎用転送機能(サーバ間、システム間のファイル連携およびファイル削除)。
# 機 能:引数と同名の設定ファイル(CSV)に従い、ファイルを GET/PUT/DEL する。
# 処理はファイルの先頭から順番に実行される。
#
# ※設定ファイル(conf/${EXEC_ID}.csv)の書式は通常のカンマ区切り(引用符なし)。
# カンマ前後の空白文字(半角スペース、タブ、行末の改行)は無視される。
# 文字列にカンマが含まれる場合は想定していない。
#
# 01. 有効フラグ :0/1から選択。1で有効、0で無効(コメント扱い)。
#
# 02. プロトコル :SCP/SFTP/FTPから選択。ただしメソッドがDELの場合は、空(ローカルファイル削除)/SFTP/FTP から選択。
#
# 03. メソッド :GET/PUT/DELから選択。
#
# 04. サーバ名 :FTP_CONFの設定ファイル名(/opt/mdsbatch/bin/lib/INIT/.サーバ名)。ローカルファイル削除時は空。
#
# 05. ユーザ名 :FTP_CONFに書かれたユーザ名。ローカルファイル削除時は空。
#
# 06. 転送元パス :GETの場合接続先サーバのパス。PUTの場合ローカルのパス。DELの場合はリモート/ローカルにかかわらず、ここに対象ファイルを記載。
# ローカルに相対パスを記載した場合、カレントディレクトリは/opt/mdsbatch/bin/transfer/data/となる。
# ディレクトリ("/"で終わる)は指定不可。
# PUTの場合、空にすると空ファイルを作成して転送する。
#
# ファイル名に含まれるワイルドカード「*」と「?」は展開される。
# その場合、転送先パスは必ずディレクトリを指定すること。
#
# POSIX形式(strftimeの形式)を指定すると、引数の日付・現在時刻が埋め込まれる。
# POSIXにはないが、%.nSで、マイクロ秒の上n桁に置換する。
# 例:file_%Y%M%D_%H%M%S_%.3S.txt → file_20160113_142536_123.txt
#
# 07. 転送先パス :GETの場合ローカルのパス。PUTの場合接続先サーバのパス。DELの場合は空にすること。
# ローカルに相対パスを記載した場合、カレントディレクトリは/opt/mdsbatch/bin/transfer/data/となる。
# ファイル名に含まれるワイルドカードは展開されない。
# 日付置換の記載方法は転送元と同じ。
#
# 08. リトライ設定 :処理が失敗した場合のリトライ設定。空の場合はリトライせず、エラーとなる(「エラー時の処理」に従って遷移)。
# 「間隔(秒)*回数」形式で指定した場合は、n秒間隔でm回実行する。
# 例:60*2 … 失敗すると1分後に再実行、それでも失敗ならさらに1分後に再実行して、失敗なら「エラー時の処理」に従う
#
# 09. エラー時の処理:STOP/NEXT/SKIPから選択。
# STOPを指定した処理が失敗した場合、その場でバッチは異常終了する。
# NEXTを指定した処理が失敗した場合、次の転送を実施するが、最終的にバッチは異常終了する。
# SKIPを指定した処理が失敗した場合、エラーとせずに次の転送を実施する(そのままいけば正常終了)。
#
# 10. オプション :プロトコルごとに指定可能なオプション。カンマ区切りで複数指定可能。
# ・SCPの場合 :scpコマンドのオプションを指定。
# 何も指定しなくとも、デフォルトで「-2」オプションは指定される。
# 例:「-4,-i /home/mdsbatch/.ssh/id_rsa」 …IPV4強制、鍵ファイルを指定
# ・SFTPの場合:sftpコマンドのオプションを指定。
# バッチファイル実行の「-b」オプションはここでは指定できない(しても上書きする)。
# 例:「-4,oIdentityFile=/home/mdsbatch/.ssh/id_rsa」 …IPV4強制、鍵ファイルを指定
# ・FTPの場合 :PerlのNet::Ftpのnew()に指定するオプション(ハッシュ)を、「キー=値」形式で指定。
# 例:「Passive=1,Timeout=180」 …PASVモードをON、タイムアウトを180に設定
#
# ------------------------------------------------------------------------------
# 再ラン:単純再ラン可能(INファイルが他の処理で削除されていない前提)
# ------------------------------------------------------------------------------
# 引 数:$EXEC_ID :設定ファイル名(拡張子抜き)
# :$ARG_DATE :処理日
# :$CHECK :チェックフラグ(なんらかの値を指定すると設定のチェックのみ実施)
# ------------------------------------------------------------------------------
# 履 歴:2016/01/13 システム修正依頼No.720 レンディングデータ業者へのファイル伝送 新規作成
# 2019/10/23 mdsbatch@d-batch01/02に導入するため、千手ログ部分削除、関連path修正
################################################################################
use strict;
use warnings;
use Sys::Hostname qw(hostname);
use Jcode;
use POSIX qw(strftime);
use Time::HiRes qw(gettimeofday);
use FindBin qw($Bin);
use Net::FTP;
use File::Basename qw(dirname basename);
use File::Path;
use lib "$Bin/lib";
use ComLog;
use DateUtils;
use INIT::FTP_CONF;
# 引数
my ($EXEC_ID, $ARG_DATE, $CHECK) = @ARGV;
# 種別自体はあまり参考にしないため、原則「OTHER_ERROR」を設定すること。
my $ERROR_ID;
my $LOG_PATH;
my $DATA_DIR = "$Bin/data";
my $ET10;
################################################################################
# メインコントロール
################################################################################
&subInit();
&subMain();
&subExit();
################################################################################
# 初期処理
################################################################################
sub subInit {
eval {
# ログ処理
$LOG_PATH = ComLog::open('addNames' => $EXEC_ID) or die 'ログファイルが開けませんでした。';
ComLog::startInit();
ComLog::start('引数チェック');
# 引数チェック
if (not defined($ARG_DATE)) {
die("引数1(処理日)が指定されていません。");
}
if (not &isDate($ARG_DATE)) {
die("引数1(処理日)が不正な日付です:$ARG_DATE");
}
if (not defined($EXEC_ID)) {
die("引数2(設定ファイル名)が指定されていません。");
}
if (not -f ("$Bin/conf/${EXEC_ID}.csv")) {
die(
"引数2(設定ファイル名)の設定ファイルが存在しません:$Bin/conf/${EXEC_ID}.csv"
);
}
ComLog::end('引数チェック');
};
if ($@) {
ComLog::write('ERROR', $@);
$ERROR_ID = 'OTHER_ERROR';
&subExit();
}
ComLog::endInit();
}
################################################################################
# 主処理
################################################################################
sub subMain {
ComLog::startMain();
eval {
my @configs = ();
my %connection = ();
my @delete_files = ();
ComLog::start('設定ファイル読み込み');
# エラー行カウント
my $error_count = 0;
open(my $conf, '<', "$Bin/conf/${EXEC_ID}.csv")
or die "設定ファイル読み込みに失敗しました:$Bin/conf/${EXEC_ID}.csv";
while (my $config_record = <$conf>) {
my $no = $.;
chomp($config_record);
# 空行は一応スキップ
if ($config_record =~ /^\s*$/) {
ComLog::write("$no行目:空行により、スキップ");
next;
}
ComLog::write("$no行目:$config_record");
# この行にエラーがあったか?
my $error = 0;
my %config_columns = ();
@config_columns{ 'enabled', 'protocol', 'method', 'server', 'user', 'from', 'to', 'retry', 'on_error',
'options' } = split(/,/, $config_record, 10);
foreach my $column (keys(%config_columns)) {
if (defined($config_columns{$column})) {
$config_columns{$column} =~ s/^\s+//;
$config_columns{$column} =~ s/\s+$//;
}
if (!defined($config_columns{$column})) {
$config_columns{$column} = '';
}
}
# 有効フラグ
if ($config_columns{'enabled'} eq '0') {
ComLog::write("$no行目:無効に設定された設定です。スキップします。");
next;
} elsif ($config_columns{'enabled'} eq '1') {
delete($config_columns{'enabled'});
} elsif ($config_columns{'enabled'} eq '') {
ComLog::write('ERROR',
"$no行目:有効フラグが指定されていません。0か1のどちらかを指定してください。"
);
$error = 1;
} else {
ComLog::write('ERROR',
"$no行目:有効フラグが無効です($config_columns{'enabled'})。0か1のどちらかを指定してください。"
);
$error = 1;
}
# プロトコルとメソッド
if ($config_columns{'method'} eq '') {
ComLog::write('ERROR',
"$no行目:メソッドが指定されていません。GET、PUT、DELのどれかを指定してください。"
);
$error = 1;
} elsif (scalar(grep { $_ eq $config_columns{'method'} } ('GET', 'PUT', 'DEL')) == 0) {
ComLog::write('ERROR',
"$no行目:メソッドが不正です($config_columns{'method'})。GET、PUT、DELのどれかを指定してください。"
);
$error = 1;
} elsif ($config_columns{'method'} eq 'DEL') {
if (scalar(grep { $_ eq $config_columns{'protocol'} } ('', 'SFTP', 'FTP')) == 0) {
ComLog::write('ERROR',
"$no行目:プロトコルが不正です($config_columns{'protocol'})。メソッドがDELの場合、SFTP、FTPのどちらかを指定するか、空にしてください。"
);
$error = 1;
}
} else {
if ($config_columns{'protocol'} eq '') {
ComLog::write('ERROR',
"$no行目:プロトコルが指定されていません。SCP、SFTP、FTPのどれかを指定してください。"
);
$error = 1;
} elsif (scalar(grep { $_ eq $config_columns{'protocol'} } ('SCP', 'SFTP', 'FTP')) == 0) {
ComLog::write('ERROR',
"$no行目:プロトコルが不正です($config_columns{'protocol'})。SCP、SFTP、FTPのどれかを指定してください。"
);
$error = 1;
}
}
# サーバ名、ユーザ名
if ($config_columns{'protocol'} eq '' and $config_columns{'method'} eq 'DEL') {
if ($config_columns{'server'} ne '') {
ComLog::write('ERROR',
"$no行目:サーバ名が指定されています。ローカルファイル削除時は空にしてください。");
$error = 1;
}
if ($config_columns{'user'} ne '') {
ComLog::write('ERROR',
"$no行目:ユーザ名が指定されています。ローカルファイル削除時は空にしてください。"
);
$error = 1;
}
} else {
if ($config_columns{'server'} eq '') {
ComLog::write('ERROR',
"$no行目:サーバ名が空です。FTP_CONFのサーバ名を指定してください。");
$error = 1;
}
if ($config_columns{'user'} eq '') {
ComLog::write('ERROR',
"$no行目:ユーザ名が空です。サーバ名に指定したFTP_CONFの設定ファイル内のユーザ名を指定してください。"
);
$error = 1;
}
}
if ($config_columns{'server'} ne '' and $config_columns{'user'} ne '') {
# 転送元パスのサーバ名とユーザ名から、FTP_CONFのインスタンスを作成して保存しておく
my $connection_key = "$config_columns{'user'}\@$config_columns{'server'}";
eval {
if (!exists($connection{$connection_key})) {
$connection{$connection_key} = FTP_CONF->new(@config_columns{ 'server', 'user' });
}
};
if ($@) {
ComLog::write('ERROR', "$no行目:サーバ名が不正です:$@");
$error = 1;
} elsif (!defined($connection{$connection_key}->getServerAddr())
or !defined($connection{$connection_key}->getUserName())) {
ComLog::write('ERROR',
"$no行目:ユーザ名が不正です。FTP_CONFから設定を取得できませんでした。"
);
$error = 1;
} else {
$config_columns{'connection'} = $connection{$connection_key};
}
}
# 転送元パス、転送先パス
# 「.」と「..」はディレクトリのため、「/」をつける
if ($config_columns{'from'} =~ /^\.\.?$/ or $config_columns{'from'} =~ /\/\.\.?$/) {
$config_columns{'from'} .= '/';
}
if ($config_columns{'to'} =~ /^\.\.?$/ or $config_columns{'to'} =~ /\/\.\.?$/) {
$config_columns{'to'} .= '/';
}
if ($config_columns{'from'} =~ /\/$/) {
ComLog::write('ERROR',
"$no行目:転送元パスが不正です($config_columns{'from'})。ディレクトリではなくファイルを指定してください。"
);
$error = 1;
}
if ($config_columns{'from'} =~ /[\*\?]/ and $config_columns{'to'} ne '' and $config_columns{'to'} !~ /\/$/)
{
ComLog::write('ERROR',
"$no行目:転送先パスが不正です($config_columns{'to'})。転送元にワイルドカードを含む場合は、転送先には必ずディレクトリを指定してください。"
);
$error = 1;
}
# メソッド毎に違う部分のチェック
if ($config_columns{'method'} eq 'GET') {
if ($config_columns{'from'} eq '') {
ComLog::write('ERROR',
"$no行目:転送元パスが空です。接続先サーバのパスを指定してください。");
$error = 1;
}
if ($config_columns{'to'} eq '') {
$config_columns{'to'} = './'
}
} elsif ($config_columns{'method'} eq 'PUT') {
# PUTの場合、転送元パスが空の場合はローカルに空ファイルを作成して転送するため、転送先がファイルであればOK
if ($config_columns{'from'} eq '') {
if ($config_columns{'to'} eq '') {
ComLog::write('ERROR',
"$no行目:転送元パスも転送先パスも空です。パスを指定してください。"
);
$error = 1;
} elsif ($config_columns{'to'} =~ /\/$/) {
ComLog::write('ERROR',
"$no行目:転送元パスが空で、転送先パスがディレクトリです。空ファイルを作成する場合、転送先パスには接続先サーバのファイルを指定してください。"
);
$error = 1;
}
} elsif ($config_columns{'to'} eq '') {
$config_columns{'to'} = './'
}
} elsif ($config_columns{'method'} eq 'DEL') {
if ($config_columns{'from'} eq '') {
ComLog::write('ERROR',
"$no行目:転送元パスが空です。削除する接続先サーバのファイルパスを指定してください。");
$error = 1;
}
if ($config_columns{'to'} ne '') {
ComLog::write('ERROR',
"$no行目:転送先パスが空ではありません($config_columns{'to'})。DELの場合は空にしてください。"
);
$error = 1;
}
}
# リトライ設定
if ($config_columns{'retry'} eq '') {
@config_columns{ 'retry_count', 'retry_span' } = (0, 0);
} elsif ($config_columns{'retry'} =~ /^(\d+)\s*\*\s*(\d+)$/) {
@config_columns{ 'retry_count', 'retry_span' } = (0 + $1, 0 + $2);
} else {
ComLog::write('ERROR',
"$no行目:リトライ設定が無効です($config_columns{'retry'})。「間隔(秒)*回数」形式で指定してください。"
);
$error = 1;
}
# エラー時の処理
if (scalar(grep { $_ eq $config_columns{'on_error'} } ('STOP', 'NEXT', 'SKIP')) == 0) {
ComLog::write('ERROR',
"$no行目:エラー時の処理が無効です($config_columns{'on_error'})。STOP、NEXT、SKIPのどれかを指定してください。"
);
$error = 1;
}
# オプション
my %options = ();
if (defined($config_columns{'options'})) {
foreach my $option (split(/\s*,\s*/, $config_columns{'options'})) {
$options{$option} = '';
}
}
$config_columns{'options'} = \%options;
# 転送元・転送先ファイルパスの日時部分を置換
my $base_time = time();
if ($ARG_DATE ne &getToday()) {
$base_time = $base_time - &getTimeValue(&getToday()) + &getTimeValue($ARG_DATE);
}
my $microsecond;
if ($config_columns{'from'} =~ /[^%]?%/) {
while ($config_columns{'from'} =~ /[^%]?%\.([1-6])S/) {
(undef, $microsecond) = &gettimeofday();
$microsecond = substr(sprintf("%06d", $microsecond), 0, $1);
$config_columns{'from'} =~ s/([^%]?)%\.[1-6]S/$1$microsecond/;
}
$config_columns{'from'} = &strftime($config_columns{'from'}, localtime($base_time));
}
if ($config_columns{'to'} =~ /[^%]?%/) {
while ($config_columns{'to'} =~ /[^%]?%\.([1-6])S/) {
(undef, $microsecond) = &gettimeofday();
$microsecond = substr(sprintf("%06d", $microsecond), 0, $1);
$config_columns{'to'} =~ s/([^%]?)%\.[1-6]S/$1$microsecond/;
}
$config_columns{'to'} = &strftime($config_columns{'to'}, localtime($base_time));
}
if ($error == 0) {
if (defined($CHECK) and $CHECK ne '') {
ComLog::write("$no行目:エラーなし");
}
push(@configs, \%config_columns);
} else {
$error_count++;
}
}
close($conf);
ComLog::end('設定ファイル読み込み');
if (scalar(@configs) == 0) {
ComLog::write('WARN', '設定ファイルに有効な転送設定が1つもありませんでした。');
}
if ($error_count != 0) {
die("設定ファイルにエラーのある行が$error_count行ありました。");
}
if (defined($CHECK) and $CHECK ne '') {
ComLog::write(
'設定ファイルにエラーはありませんでした。コマンドの引数でチェックフラグが指定されているため、ここで処理を終了します。'
);
} else {
ComLog::start('ファイル転送');
foreach my $config (@configs) {
# リトライ用ループ
$config->{'retry_count'}++;
for (my $i = 0; $i < $config->{'retry_count'}; $i++) {
chdir($DATA_DIR);
# GET
if ($config->{'method'} eq 'GET') {
ComLog::write("ファイルをGETします。$config->{'from'} → $config->{'to'}");
$config->{'result'} = &get($config);
# PUT
} elsif ($config->{'method'} eq 'PUT') {
# 空ファイル作成
my $empty_file = 0;
if ($config->{'from'} eq '') {
$config->{'from'} = &basename($config->{'to'});
ComLog::write("空ファイルを作成します:$config->{'from'}");
if (open(my $from, '>', $config->{'from'})) {
close($from);
$empty_file = 1;
} else {
ComLog::write("ファイルの作成に失敗しました:$config->{'from'}");
$config->{'result'} = 0;
}
}
if (!exists($config->{'result'})) {
ComLog::write("ファイルをPUTします。$config->{'from'} → $config->{'to'}");
$config->{'result'} = &put($config);
if ($empty_file == 1) {
unlink($config->{'from'});
}
}
# DEL
} elsif ($config->{'method'} eq 'DEL') {
ComLog::write("ファイルをDELします。$config->{'from'}");
$config->{'result'} = &del($config);
}
if ($config->{'result'} == 1) {
# 成功したらリトライしない
last;
} else {
sleep($config->{'retry_span'});
}
}
# リトライループを抜けてもエラーのままの場合
if ($config->{'result'} == 0) {
if ($config->{'on_error'} eq 'SKIP') {
ComLog::write(
'ファイル転送に失敗しました。スキップします(異常終了にはなりません)。'
);
} elsif ($config->{'on_error'} eq 'NEXT') {
ComLog::write(
'ファイル転送に失敗しました。次のファイルを処理します(最後に異常終了します)。'
);
} else {
ComLog::write(
'ファイル転送に失敗しました。処理を終了します(異常終了します)。'
);
last;
}
}
}
ComLog::end('ファイル転送');
# スキップ以外の設定で、エラーだったものがある場合は異常終了
if (grep { $_->{'on_error'} ne 'SKIP' and exists($_->{'result'}) and $_->{'result'} == 0 } (@configs)) {
die("ファイル転送に失敗しました。");
}
}
};
if ($@) {
ComLog::write('ERROR', $@);
$ERROR_ID = 'OTHER_ERROR';
&subExit();
}
ComLog::endMain();
}
#################################################################################
# 終了処理
################################################################################
sub subExit {
ComLog::startExit();
my $return_value = 0;
eval {
# エラー処理
if (defined($ERROR_ID)) {
# エラー発生時
ComLog::write('NG', '処理中にエラーが発生しました。処理を中止します。');
$return_value = 9;
} else {
# 正常終了時
ComLog::write('OK', '処理は正常に終了しました。');
}
# ログ処理
ComLog::endExit();
ComLog::close();
exit($return_value);
};
if ($@) {
exit(9);
}
}
################################################################################
# 名 称:get
# 機 能:ファイルを取得する。
# ------------------------------------------------------------------------------
# 引 数:config … (必須)転送設定のハッシュ
# ------------------------------------------------------------------------------
# 戻り値:0/1 … 失敗/成功
################################################################################
sub get {
my ($config) = @_;
my $result = 0;
my $connection = $config->{'connection'};
my $server = $connection->getServerAddr();
my $user = $connection->getUserName();
my $password = $connection->getPassword();
my $from = $config->{'from'};
my $to = $config->{'to'};
my $from_dir = &dirname($from);
my $from_file = &basename($from);
my $to_dir;
my $to_file;
# 「/」で終わる場合、dirnameとbasenameはうまく動かないため使わない
if ($to =~ /\/$/) {
$to_dir = $to;
$to_file = '';
} else {
$to_dir = &dirname($to);
$to_file = &basename($to);
}
eval {
if (! -d $to_dir) {
&mkpath($to_dir, { 'verbose' => 1 });
}
if ($config->{'protocol'} eq 'SCP') {
# オプションを設定
my %options = %{ $config->{'options'} };
if (!exists($options{'-1'})) {
$options{'-2'} = '';
}
my $option = join(' ', %options);
if ($option !~ /\-oBatchMode/) {
$option .= ' -oBatchMode=yes';
}
my $command = qq(/usr/bin/scp $option "$user\@$server:$from" "$to");
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
if ($? != 0 and defined($password)) {
# パスワード認証
ComLog::write("鍵認証での実行失敗。パスワード認証で実行します。");
$option =~ s/\-oBatchMode=yes//;
$command = qq(echo '$password' | $Bin/lib/pass.sh /usr/bin/scp $option "$user\@$server:$from" "$to");
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
}
if ($? == 0) {
ComLog::write("成功。");
$result = 1;
} else {
ComLog::write("失敗。リターンコード:" . ($? >> 8) . "、$!");
$result = 0;
}
} elsif ($config->{'protocol'} eq 'SFTP') {
# オプションを設定
my %options = %{ $config->{'options'} };
$options{'-b'} = "$DATA_DIR/${EXEC_ID}_$$.bat";
my $option = join(' ', %options);
if ($option !~ /\-oBatchMode/) {
$option .= ' -oBatchMode=yes';
}
# バッチファイル作成
open(my $sftp_bat, '>', $options{'-b'})
or die "SFTP用バッチファイルのオープンに失敗しました。$options{'-b'}";
print($sftp_bat "cd '$from_dir'\n");
print($sftp_bat "lcd '$to_dir'\n");
if ($from_file =~ /[\*\?]/) {
print($sftp_bat "mget '$from_file'\n");
} elsif ($to_file eq '') {
print($sftp_bat "get '$from_file'\n");
} else {
print($sftp_bat "get '$from_file' '$to_file'\n");
}
close($sftp_bat);
# バッチファイル実行
my $command = qq(/usr/bin/sftp $option $user\@$server);
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
if ($? != 0 and defined($password)) {
# パスワード認証
ComLog::write("鍵認証での実行失敗。パスワード認証で実行します。");
$option =~ s/\-oBatchMode=yes//;
$command = qq(echo '$password' | $Bin/lib/pass.sh /usr/bin/sftp $option $user\@$server);
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
}
if ($? == 0) {
ComLog::write("成功。");
$result = 1;
} else {
ComLog::write("失敗。リターンコード:" . ($? >> 8) . "、$!");
$result = 0;
}
unlink($options{'-b'});
} elsif ($config->{'protocol'} eq 'FTP') {
# オプションを設定
my %options = ('Debug' => 1);
foreach my $option (keys(%{ $config->{'options'} })) {
my ($key, $value) = split(/\s*=\s*/, $option);
$options{$key} = $value;
}
$options{'Hash'} = \*STDERR;
chdir($to_dir);
my $ftp = Net::FTP->new($server, %options) or die "サーバ$serverへの接続に失敗しました:$@";
$ftp->login($user, $password)
or die "サーバ$serverへのログインに失敗しました($user/$password):" . $ftp->message();
$ftp->binary() or die 'バイナリモードへの変更に失敗しました:' . $ftp->message();
$ftp->cwd($from_dir) or die 'ディレクトリ移動に失敗しました:' . $ftp->message();
if ($from_file =~ /[\*\?]/) {
foreach my $file ($ftp->ls($from_file)) {
$ftp->get($file) or die '転送処理に失敗しました' . $ftp->message();
}
} elsif ($to_file eq '') {
$ftp->get($from_file) or die '転送処理に失敗しました' . $ftp->message();
} else {
$ftp->get($from_file, $to_file) or die '転送処理に失敗しました' . $ftp->message();
}
$ftp->quit();
ComLog::write("成功。");
$result = 1;
}
};
if ($@) {
ComLog::write('ERROR', $@);
$result = 0;
}
return $result;
}
################################################################################
# 名 称:put
# 機 能:ファイルを転送する。
# ------------------------------------------------------------------------------
# 引 数:config … (必須)転送設定のハッシュ
# ------------------------------------------------------------------------------
# 戻り値:0/1 … 失敗/成功
################################################################################
sub put {
my ($config) = @_;
my $result = 0;
my $connection = $config->{'connection'};
my $server = $connection->getServerAddr();
my $user = $connection->getUserName();
my $password = $connection->getPassword();
my $from = $config->{'from'};
my $to = $config->{'to'};
my $from_dir = &dirname($from);
my $from_file = &basename($from);
if ($from =~ /[\*\?]/) {
my @files = glob($from);
if (scalar(@files) == 0) {
ComLog::write('ERROR', "PUT対象ファイルがローカルに1つも存在しません:$from");
return 0;
}
} else {
if (! -f $from) {
ComLog::write('ERROR', "PUT対象ファイルがローカルに存在しません:$from");
return 0;
}
}
my $to_dir;
my $to_file;
# 「/」で終わる場合、dirnameとbasenameはうまく動かないため使わない
if ($to =~ /\/$/) {
$to_dir = $to;
$to_file = '';
} else {
$to_dir = &dirname($to);
$to_file = &basename($to);
}
eval {
if ($config->{'protocol'} eq 'SCP') {
# オプションを設定
my %options = %{ $config->{'options'} };
if (!exists($options{'-1'})) {
$options{'-2'} = '';
}
my $option = join(' ', %options);
# PUTの場合は転送元がローカルのため、ワイルドカードを展開して個別に転送する
foreach my $file (glob($from)) {
if ($option !~ /\-oBatchMode/) {
$option .= ' -oBatchMode=yes';
}
my $command = qq(/usr/bin/scp $option $file "$user\@$server:$to");
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
if ($? != 0 and defined($password)) {
# パスワード認証
ComLog::write("鍵認証での実行失敗。パスワード認証で実行します。");
$option =~ s/\-oBatchMode=yes//;
$command = qq(echo '$password' | $Bin/lib/pass.sh /usr/bin/scp $option $file "$user\@$server:$to");
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
}
if ($? == 0) {
ComLog::write("成功。");
$result = 1;
} else {
ComLog::write("失敗。リターンコード:" . ($? >> 8) . "、$!");
$result = 0;
last;
}
}
} elsif ($config->{'protocol'} eq 'SFTP') {
my %options = %{ $config->{'options'} };
$options{'-b'} = "$DATA_DIR/${EXEC_ID}_$$.bat";
my $option = join(' ', %options);
if ($option !~ /\-oBatchMode/) {
$option .= ' -oBatchMode=yes';
}
# バッチファイル作成
open(my $sftp_bat, '>', $options{'-b'})
or die "SFTP用バッチファイルのオープンに失敗しました。$options{'-b'}";
print($sftp_bat "lcd '$from_dir'\n");
print($sftp_bat "cd '$to_dir'\n");
if ($from_file =~ /[\*\?]/) {
print($sftp_bat "mput '$from_file'\n");
} elsif ($to_file eq '') {
print($sftp_bat "put '$from_file'\n");
} else {
print($sftp_bat "put '$from_file' '$to_file'\n");
}
close($sftp_bat);
# バッチファイル実行
my $command = qq(/usr/bin/sftp $option $user\@$server);
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
if ($? != 0 and defined($password)) {
# パスワード認証
ComLog::write("鍵認証での実行失敗。パスワード認証で実行します。");
$option =~ s/\-oBatchMode=yes//;
$command = qq(echo '$password' | $Bin/lib/pass.sh /usr/bin/sftp $option $user\@$server);
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
}
if ($? == 0) {
ComLog::write("成功。");
$result = 1;
} else {
ComLog::write("失敗。リターンコード:" . ($? >> 8) . "、$!");
$result = 0;
}
unlink($options{'-b'});
} elsif ($config->{'protocol'} eq 'FTP') {
# オプションを設定
my %options = ('Debug' => 1);
foreach my $option (keys(%{ $config->{'options'} })) {
my ($key, $value) = split(/\s*=\s*/, $option);
$options{$key} = $value;
}
$options{'Hash'} = \*STDERR;
chdir($from_dir);
my $ftp = Net::FTP->new($server, %options) or die "サーバ$serverへの接続に失敗しました:$@";
$ftp->login($user, $password)
or die "サーバ$serverへのログインに失敗しました($user/$password):" . $ftp->message();
$ftp->binary() or die 'バイナリモードへの変更に失敗しました:' . $ftp->message();
$ftp->cwd($to_dir) or die 'ディレクトリ移動に失敗しました:' . $ftp->message();
if ($from_file =~ /[\*\?]/) {
foreach my $file (glob($from_file)) {
$ftp->put($file) or die '転送処理に失敗しました' . $ftp->message();
}
} elsif ($to_file eq '') {
$ftp->put($from_file) or die '転送処理に失敗しました' . $ftp->message();
} else {
$ftp->put($from_file, $to_file) or die '転送処理に失敗しました' . $ftp->message();
}
$ftp->quit();
ComLog::write("成功。");
$result = 1;
}
};
if ($@) {
ComLog::write('ERROR', $@);
$result = 0;
}
return $result;
}
################################################################################
# 名 称:del
# 機 能:ファイルを削除する。
# ------------------------------------------------------------------------------
# 引 数:config … (必須)転送設定のハッシュ
# ------------------------------------------------------------------------------
# 戻り値:0/1 … 失敗/成功
################################################################################
sub del {
my ($config) = @_;
my $result = 0;
my $from = $config->{'from'};
eval {
# ローカル
if ($config->{'protocol'} eq '') {
if ($from =~ /[\*\?]/) {
my $del_count = 0;
foreach my $file (glob($from)) {
unlink($file) or die "削除処理に失敗しました:$file";
$del_count++;
}
if ($del_count == 0) {
die("削除対象ファイルが存在しません:$from");
} else {
ComLog::write("成功。");
$result = 1;
}
} else {
if (-f $from) {
unlink($from) or die "削除処理に失敗しました:$from";
ComLog::write("成功。");
$result = 1;
} else {
die("削除対象ファイルが存在しません:$from");
}
}
} else {
my $connection = $config->{'connection'};
my $server = $connection->getServerAddr();
my $user = $connection->getUserName();
my $password = $connection->getPassword();
my $from_dir = &dirname($from);
my $from_file = &basename($from);
if ($config->{'protocol'} eq 'SFTP') {
# オプションを設定
my %options = %{ $config->{'options'} };
$options{'-b'} = "$DATA_DIR/${EXEC_ID}_$$.bat";
my $option = join(' ', %options);
if ($option !~ /\-oBatchMode/) {
$option .= ' -oBatchMode=yes';
}
# バッチファイル作成
open(my $sftp_bat, '>', $options{'-b'})
or die "SFTP用バッチファイルのオープンに失敗しました。$options{'-b'}";
print($sftp_bat "cd '$from_dir'\n");
print($sftp_bat "rm '$from_file'\n");
close($sftp_bat);
# バッチファイル実行
my $command = qq(/usr/bin/sftp $option $user\@$server);
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
if ($? != 0 and defined($password)) {
# パスワード認証
ComLog::write("鍵認証での実行失敗。パスワード認証で実行します。");
$option =~ s/\-oBatchMode=yes//;
$command = qq(echo '$password' | $Bin/lib/pass.sh /usr/bin/sftp $option $user\@$server);
ComLog::write("コマンド:$command");
ComLog::write(`$command`);
}
if ($? == 0) {
ComLog::write("成功。");
$result = 1;
} else {
ComLog::write("失敗。リターンコード:" . ($? >> 8) . "、$!");
$result = 0;
}
unlink($options{'-b'});
} elsif ($config->{'protocol'} eq 'FTP') {
# オプションを設定
my %options = ('Debug' => 1);
foreach my $option (keys(%{ $config->{'options'} })) {
my ($key, $value) = split(/\s*=\s*/, $option);
$options{$key} = $value;
}
$options{'Hash'} = \*STDERR;
my $ftp = Net::FTP->new($server, %options) or die "サーバ$serverへの接続に失敗しました:$@";
$ftp->login($user, $password)
or die "サーバ$serverへのログインに失敗しました($user/$password):" . $ftp->message();
$ftp->binary() or die 'バイナリモードへの変更に失敗しました:' . $ftp->message();
$ftp->cwd($from_dir) or die 'ディレクトリ移動に失敗しました:' . $ftp->message();
if ($from_file =~ /[\*\?]/) {
foreach my $file ($ftp->ls($from_file)) {
$ftp->delete($file) or die '削除処理に失敗しました' . $ftp->message();
}
} else {
$ftp->delete($from_file) or die '削除処理に失敗しました' . $ftp->message();
}
$ftp->quit();
ComLog::write("成功。");
$result = 1;
}
}
};
if ($@) {
ComLog::write('ERROR', $@);
$result = 0;
}
return $result;
}