ftpコマンドの使いかた

ファイル転送の一般的な手順は

  1. ファイル転送を行う計算機と接続する
  2. 目的のディレクトリへ移動
  3. ファイル転送
  4. 接続を切り,終了
となります. これらの手順は,ほとんどftpのサブコマンドで 行ないます.

 

ftpのプロンプトが出ている状態で,

ftp> help
と入力すると,使えるサブコマンドの一覧がでます.
使えるサブコマンドは,計算機によって異なる可能性があります. よって,以下で説明するサブコマンドが使えない可能性もあります.
更に,
ftp> help subcommand
とすると,サブコマンドsubcommandに 対する説明が,簡単に表示されます.

 

最低限覚えておくべきサブコマンドは,以下の通りです.

open
接続する.
get (mget)
(複数の)ファイルをkyu-ccから取ってくる.
put (mput)
(複数の)ファイルをkyu-ccへ送る.
ascii, binary
ファイル転送モードをアスキー,又はバイナリにする.
dir, ls
ファイルのリストを表示する.
cd
ディレクトリ移動する.
!
接続元のシェルへ退避する
close
接続を切断する.
exit
ftpを終了する.
これらのサブコマンドは,完全に指定する必要はなく, サブコマンドの中で,一意に判別できる長さを入力すれば十分です. 例えば,"as"で始まるサブコマンドが asciiだけの場合は,
ftp> as 
まで入力すれば,ascii を指定したことになります.

 

接続

ftpを使って, kyu-ccとの接続を行うには

local% ftp kyu-cc.cc.kyushu-u.ac.jp
Connected to 133.5.8.9.
220 kyu-cc FTP server (UNIX(r) System V Release 4.0) ready.
Name (133.5.8.9:user): username               <-ユーザ名
Password: ******                              <- パスワード
と表示されます. Nameにはデフォルトでは, localにおけるユーザ名 が表示されます(上の例ではuser). そのままリターンキーを押すとuserで,接続を試みます. localkyu-ccにおける ユーザ名が違う場合は,ここで正しいユーザ名を入力してください. これで,接続が完了します. 接続後は,kyu-ccの ホームディレクトリにいることになります.

 

上の接続手順は, ftpのサブコマンドでも行うことができます. まずftpを起動します. ここで,openサブコマンドを使って

local% ftp
ftp> open kyu-cc.cc.kyushu-u.ac.jp
とします.

 

目的のディレクトリへ移動する

ファイルをkyu-ccからとってくる場合, 最初に,目的のファイルのあるディレクトリへ移動する必要があります. 逆に,ファイルをkyu-ccへ置く場合も, ファイルを置くディレクトリへ移動する必要があります. このような接続先でのディレクトリ移動にはcd サブコマンドを使います. 目的のディレクトリがdirectoryだとすると,

ftp> cd directory
とします. 現在のディレクトリにあるファイル(含むディレクトリ)を表示するには
ftp> dir
ftp> ls
などとしてください.両者は,表示形式が違います. また,両者とも,引数にディレクトリを渡すことができます. 引数にディレクトリを渡した場合,カレントディレクトリではなく, そのディレクトリにあるファイルが表示されます.

 

新規にディレクトリを作ったり,ファイル(含むディレクトリ)の名前を変えたり することもできます.詳しくはマニュアルを参照してください.

接続先(kyu-cc)でのディレクトリ移動 だけでなく,接続元(local) のディレクトリを移動したい場合があります. このような場合は,

ftp>lcd directory
としてください.
接続元でのディレクトリ変更は,以下のように書いていましたが, 間違いです(SolarisとFreeBSD付属のftpで確認). このような場合は,"!"を使って
ftp>!cd directory
としてください.(2000/2/8)
カレントディレクトリにあるファイルを見るには,
ftp>!ls
としてください.

 

接続元に対するサブコマンドが,あらかじめ用意されている場合もあります. 例えば,cdに対して, lcdが接続元でのディレクトリの移動を行ないます. 一般に,サブコマンドの前に"l"(エル)が付く場合は,接続元に対するサブコマンド であることが多いようです.

ファイルの転送を行う

ファイルの転送を行う前に,転送のモードを指定しておく必要があります. 転送するファイルがアスキーファイルの場合は, 転送のモード指定は,

ftp> ascii
とします.バイナリファイルの場合は
ftp> binary
とします.

 

転送モードの指定が終わったら,実際にファイル転送を行ないます. ファイルをkyu-ccから取ってくるには

ftp> get filename
とします.保存するときのファイル名を別にする場合は
ftp> get filename filename2
とします.これでfilename2という名前で保存されます. 複数のファイルを一度に取ってくるには,
ftp> mget file1 file2 file3
などとします.

 

逆に ファイルをkyu-ccへ送るには

ftp> put filename
とします. 複数のファイルを一度に送るには
ftp> mput file1 file2 file3
などとします.

 

終了する

ファイル転送が終了したら,まず

ftp> close
で接続を切ります. 他の計算機とのファイル転送が必要な場合は
ftp> open hostname
として,その計算機へ接続しなおしてください. ftpを終了する場合は,
ftp> exit
または
ftp> quit
としてください.  
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の場合、SFTPFTPのどちらかを指定するか、空にしてください。" ); $error = 1; } } else { if ($config_columns{'protocol'} eq '') { ComLog::write('ERROR', "$no行目:プロトコルが指定されていません。SCP、SFTPFTPのどれかを指定してください。" ); $error = 1; } elsif (scalar(grep { $_ eq $config_columns{'protocol'} } ('SCP', 'SFTP', 'FTP')) == 0) { ComLog::write('ERROR', "$no行目:プロトコルが不正です($config_columns{'protocol'})。SCP、SFTPFTPのどれかを指定してください。" ); $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; }
07-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值