清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
#!/usr/bin/env perl
use utf8;
use strict;
use warnings;
use 5.10.0;
use File::Copy qw/copy/;
use File::stat;
use Net::SFTP;
use Getopt::Long;
use File::Basename;
use constant {
OK => 1,
};
# --remote
# --inversion
# --cplist=file
my $help = 0;
my $remote = 0;
my $mode = "";
my $cplist = "";
my $kpath = '.'; ##need path
my $vpath = '.';
my %ssh = (
'ip' => "192.168.8.73",
'user' => "root",
'pass' => "",
);
Getopt::Long::Configure ("bundling_override");
my $ret = GetOptions( 'remote|r' => \$remote, #use ssh or local?
'cplist|c:s' => \$cplist, #copy file list
'kpath|k:s' => \$kpath, #cplist key's path
'vpath|v:s' => \$vpath, #cplits value's path
'mode|m=s' => \$mode, #mode = k || v !! k = k | left | up v = v | right | down
'ip|h:s' => \$ssh{'ip'},
'user|u:s' => \$ssh{'user'},
'pass|p:s' => \$ssh{'pass'},
'help|?', => \$help,
);
if ($help) {
say 'copy.pl --cplist | -c "copy list file config"';
say '--mode | -m = [k | v | up | down | right | left] ';
say '[--kpath | -k = ""] [--vpath | -v = ""]';
say '[--remote | -r] [--ip | -h = ""] [--user | -u = ""] [--pass | -p = ""]';
say '[--help | ?]';
exit;
}
#printOptions();
errExit('Argument parser error') if (!$ret);
if (!defined($mode = checkMode($mode))){
errExit("Mode shoud be k or v");
}
my %list = ();
if ($cplist eq "") {
errExit("Need cplist.");
} else {
%list = readList($cplist);
}
if ($remote) {
if (! &isIp($ssh{'ip'})) {
errExit('You lost host ip >_<');
}
goto GOTO_LABEL_REMOTE;
} else {
goto GOTO_LABEL_LOCAL;
}
my $sftp;
GOTO_LABEL_REMOTE:
$sftp = Net::SFTP->new($ssh{'ip'}, user => $ssh{'user'}, password => $ssh{'pass'});
if (! $sftp) {
die "Can not login $ssh{'user'}\@$ssh{'ip'}!";
} else {
say "Connect to $ssh{'ip'}:22 with $ssh{'ip'} ok";
}
sshCopyList($mode);
exit;
GOTO_LABEL_LOCAL:
localCopyList($mode);
exit;
#############################################################
#ssh
sub sshCopyList {
my $d = shift @_;
my @ks = keys(%list);
if ($d) { ##1 -> upload
foreach (@ks) {
upload_ssh_ssh($sftp, $kpath . $_, $vpath . $list{$_});
}
} else {
foreach (@ks) {
download_ssh_ssh($sftp, $kpath . $_, $vpath . $list{$_});
}
}
}
sub upload_ssh_ssh {
my ($s, $k, $v) = @_;
say 'x' x 100;
say "<1 upload $k -----> $v";
###$k -> $v
if (localExist(2, $k)) {
sshUnlink($s, 2, $v);
sshUpload($s, 3, $k, $v);
}
say '';
}
sub download_ssh_ssh {
my ($s, $k, $v, $d) = @_;
say 'x' x 100;
say "<1 download $k -----> $v";
if (sshExist($s, 2, $k)) {
localUnlink(2, $v);
sshDownload($s, 3, $k, $v);
}
say '';
}
#############################################################
#local
sub localCopyList {
my $d = shift @_;
my @ks = keys(%list);
if ($d) { ## 1 --> left -> right
foreach (@ks) {
copy_local_local($kpath . $_, $vpath . $list{$_});
}
} else {
foreach (@ks) {
copy_local_local($vpath . $list{$_}, $kpath . $_);
}
}
}
sub copy_local_local {
my ($k, $v) = @_;
say 'x' x 100;
say "<1 copy $k -----> $v";
if (localExist(2, $k)) {
localUnlink(2, $v);
localCopy(3, $k, $v);
}
say '';
}
#############################################################
# other sub part
##
sub sshDownload {
my ($sftp, $index, $src, $dest) = @_;
say "<$index download $src -> $dest";
if (defined($sftp)) {
my $ret = $sftp->get($src, $dest);
return OK if $ret;
}
return !OK;
}
sub sshUpload {
my ($sftp, $index, $src, $dest) = @_;
say "<$index upload $src -> $dest";
if (defined($sftp)) {
my $ret = $sftp->put($src, $dest);
return OK if $ret;
}
return !OK;
}
sub sshUnlink {
my ($sftp, $index, $file) = @_;
die " ----- !!! don't unlink root dir / " if $file eq '/';
if (defined($sftp) && sshExist($sftp, $index, $file)) {
my $ret = $sftp->do_remove($file);
if ($ret) {
say "<$index !!: Can not delete $file";
return !OK;
}
say "<$index unlink $file";
}
return OK;
}
sub sshExist {
my ($sftp, $index, $file) = @_;
if (defined($sftp)) {
my @x = $sftp->ls(dirname($file));
my $base = basename($file);
for my $f (@x) {
if ($f->{filename} eq $base) {
return OK;
}
}
}
say "<$index remote file $file not exist.";
return !OK;
}
sub localExist {
my ($i, $f) = @_;
if (! -e $f) {
say "<$i local file $f not exist.";
return !OK;
} else {
return OK;
}
}
sub localUnlink {
my $i = shift @_;
say "<$i delete @_" if (unlink @_);
}
sub localCopy {
my ($i, $k, $v) = @_;
say "<$i copy $k -> $v" if (copy $k, $v);
}
sub readList {
my $file = shift @_;
open my $fh, '<', $file or die "Can not open file $file";
my %ret;
foreach (<$fh>) {
chomp;
next if (/\A#/);
next if (/\A\Z/);
next if (/\A\s*\Z/);
my ($k, $v) = split(/\s+/);
$ret{$k} = $v;
}
close($fh);
%ret;
}
sub checkMode {
my $mode = shift @_;
if ($mode eq "k" || $mode eq "up" || $mode eq "left") {
return OK;
}
if ($mode eq "v" || $mode eq "down" || $mode eq "right") {
return !OK;
}
return undef;
}
sub printOptions {
say 'remote = \'' . $remote . '\'';
say 'cplist = \'' . $cplist . '\'';
say 'mode = \'' . $mode . '\'';
say 'ssh<ip> = \'' . $ssh{'ip'} . '\'';
say 'ssh<user> = \'' . $ssh{'user'} . '\'';
say 'ssh<pass> = \'' . $ssh{'pass'} . '\'';
}
sub isIp {
$_ = shift @_;
if (/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {
say $_;
return OK;
} else {
return !OK;
}
}
sub errExit {
say 'Error in file ' . __FILE__ . ' line ' .__LINE__ . ', Errmsg => [' . (shift @_) . ']';
exit;
}