情境: 我必须从一台服务器向另一台服务器传输大约3000个文件,每个文件30到35 MB(两个服务器都是IBM-AIX服务器)。 这些文件是.gz格式。它们使用gunzip命令在目的地解压缩到使用中。
我现在这样做的方式: 我已经制作了包含每个500个文件的ftp脚本的.sh文件。运行这些.sh文件时,将文件传输到目标。在目的地,我继续检查有多少文件到达,一旦100个文件到达,我为这100个文件运行gunzip,然后对于接下来的100个文件再次运行,依此类推。为了节省时间,我为一批100运行gunzip。
我的想法是什么: 我正在搜索命令或任何其他方式将我的文件ftp到目的地,一旦传输100个文件,它们就会启动解压缩但这个解压缩不应暂停传输剩下的文件。
我尝试的脚本:
ftp -n 192.168.0.22 << EOF
quote user username
quote pass password
cd /gzip_files/files
lcd /unzip_files/files
prompt n
bin
mget file_00028910*gz
! gunzip file_00028910*gz
mget file_00028911*gz
! gunzip file_00028911*gz
mget file_00028912*gz
! gunzip file_00028912*gz
mget file_00028913*gz
! gunzip file_00028913*gz
mget file_00028914*gz
! gunzip file_00028914*gz
bye
上面代码的缺点是当
时! gunzip file_00028910*gz
行正在执行,下一批的ftp,即(file_00028911 * gz)的ftp暂停,因此浪费了大量时间和带宽利用率的损失。 的! mark用于在ftp提示符下运行操作系统命令。
希望我已正确解释了我的情景。如果我得到解决方案,如果任何人已经有解决方案做回复,将更新帖子。
此致 佳日。
答案 0 :(得分:0)
由于您似乎在UNIX系统上执行此操作,因此可能已安装Perl。您可以尝试以下Perl代码:
use strict;
use warnings;
use Net::FTP;
my @files = @ARGV; # get files from command line
my $server = '192.168.0.22';
my $user = 'username';
my $pass = 'password';
my $gunzip_after = 100; # collect up to 100 files
my $ftp = Net::FTP->new($server) or die "failed connect to the server: $!";
$ftp->login($user,$pass) or die "login failed";
my $pid_gunzip;
while (1) {
my @collect4gunzip;
GET_FILES:
while (my $file = shift @files) {
my $local_file = $ftp->get($file);
if ( ! $local_file ) {
warn "failed to get $file: ".$ftp->message;
next;
}
push @collect4gunzip,$local_file;
last if @collect4gunzip == $gunzip_after;
}
@collect4gunzip or last; # no more files ?
while ( $pid_gunzip && kill(0,$pid_gunzip)) {
# gunzip is still running, wait because we don't want to run multiple
# gunzip instances at the same time
warn "wait for last gunzip to return...\n";
wait();
# instead of waiting for gunzip to return we could go back to retrieve
# more files and add them to @collect4gunzip
# goto GET_FILES;
}
# last gunzip is done, start to gunzip collected files
defined( $pid_gunzip = fork()) or die "fork failed: $!";
if ( ! $pid_gunzip ) {
# child process should run gunzip
# maybe one needs so split it into multipl gunzip calls to make
# sure, that the command line does not get too long!!
system( ['gunzip', @collect4gunzip ]);
# child will exit once done
exit(0);
}
# parent continues with getting more files
}
它没有经过测试,但至少它通过了语法检查。
答案 1 :(得分:0)
两种解决方案之一。不要直接打电话给gunzip。称“blah”和“blah”是一个剧本:
#!/bin/sh
gunzip "$@" &
所以将gunzip放入后台,脚本立即返回,然后继续使用FTP。另一个想法就是添加&amp;对sh命令 - 我打赌这也会起作用。即在ftp脚本中,执行:
! gunzip file_00028914*gz &
但是......我相信你在某种程度上把自己误入歧途。 rsync和其他解决方案是有很多原因的。