0

シナリオ: あるサーバーから別のサーバーに、それぞれ 30 から 35 MB の約 3000 個のファイルを転送する必要があります (両方のサーバーは IBM-AIX サーバーです)。これらのファイルは .gz 形式です。それらは、配布先で gunzip コマンドを使用して解凍されます。

私が現在行っている方法: それぞれ 500 ファイルの ftp スクリプトを含む .sh ファイルを作成しました。これらの .sh ファイルを実行すると、ファイルが宛先に転送されます。宛先では、到着したファイルの数をチェックし続け、100 個のファイルが到着したらすぐに、これらの 100 個のファイルに対して gunzip を実行し、次の 100 個のファイルに対して同じことを繰り返します。時間を節約するために、gunzip を 100 個のバッチで実行します。

考えていること: ファイルを宛先に 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 が一時停止されるため、多くの時間が無駄になり、帯域幅の使用率が失われます。!マークは、ftp プロンプト内でオペレーティング システム コマンドを実行するために使用されます。

私のシナリオを適切に説明したことを願っています。解決策があれば投稿を更新します。既に解決策がある場合は返信してください。

よろしくヤッシュ。

4

2 に答える 2

0

2 つのソリューションのうちの 1 つ。gunzip を直接呼び出さないでください。「何とか」を呼び出し、「何とか」はスクリプトです。

#!/bin/sh
gunzip "$@" &

そのため、gunzip はバックグラウンドに置かれ、スクリプトはすぐに戻り、FTP を続行します。もう 1 つの考えは、sh コマンドに & を追加することです。これも同様に機能すると思います。つまり、ftp スクリプト内で次のように実行します。

! gunzip file_00028914*gz &

しかし... 私はあなたが少し道に迷っていると思います。rsync およびその他のソリューションは、多くの理由から進むべき道です。

于 2014-01-12T14:32:11.350 に答える
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
}

テストされていませんが、少なくとも構文チェックには合格しています。

于 2014-01-12T10:05:57.240 に答える