1

Linux 環境。このプログラム 't_show' は、ID を指定して実行すると、その ID の価格データをコンソールに書き込みます。このデータを取得する他の方法はありません。

ID 1 ~ 10,000 の価格データを 2 つのサーバー間で、最小帯域幅、最小接続数を使用してコピーする必要があります。宛先サーバーでは、データは次の形式の ID ごとに個別のファイルになります。

<id>.dat

このようなものは、長ったらしい解決策になります。

宛先:

files=`seq 1 10000`
for id in `echo $files`;
do
    ./t_show $id > $id
done
tar cf - $files | nice gzip -c  > dat.tar.gz

ソース:

scp user@source:dat.tar.gz ./
gunzip dat.tar.gz
tar xvf dat.tar

つまり、各出力を独自のファイルに書き込み、圧縮して tar し、ネットワーク経由で送信し、抽出します。

IDごとに新しいファイルを作成する必要があるという問題があります。これは大量のスペースを占有し、うまく拡張できません。

中間ファイルを作成せずに、コンソール出力を (圧縮された) tar アーカイブに直接書き込むことはできますか? より良いアイデアはありますか (圧縮データをネットワーク経由で直接書き込み、tar をスキップするなど)?

tar アーカイブは、先に述べたように、宛先サーバーで ID ごとに個別のファイルとして抽出する必要があります。

時間を割いて助けてくれた人に感謝します。

4

6 に答える 6

2

何らかの方法でフォーマットされたデータを送信し、受信側で解析することができます。

送信者の foo.sh:

#!/bin/bash
for (( id = 0; id <= 10000; id++ ))
do
    data="$(./t_show $id)"
    size=$(wc -c <<< "$data")

    echo $id $size
    cat <<< "$data"
done

受信機で:

ssh -C user@server 'foo.sh'|while read file size; do
    dd of="$file" bs=1 count="$size"
done

ssh -C転送中にデータを圧縮します

于 2011-08-19T11:35:43.593 に答える
1

少なくともtarssh 接続を介して詰め込むことができます。

tar -czf - inputfiles | ssh remotecomputer "tar -xzf -"

ただし、中間ファイルなしでアーカイブを作成する方法はわかりません。

編集:わかりました、tarファイルを手動で書くことでそれができると思います。ヘッダーはここで指定されており、それほど複雑ではないように見えますが、それは私の便利な考えではありません...

于 2011-08-19T10:52:42.333 に答える
0

私はこれを試してみます:

(for ID in $(seq 1 10000); do echo $ID: $(/t_show $ID); done) | ssh user@destination "ImportscriptOrProgram" 

これにより、「1:ValueOfID1」がstandardoutに出力され、ssh経由で宛先ホストに転送されます。宛先ホストでは、standardinから行を読み取るimportscriptまたはプログラムを開始できます。

HTH

于 2011-08-19T12:23:56.277 に答える
0

皆さんありがとう

私は「何らかの方法でフォーマットされたデータを送信し、受信機で解析するだけです」というアドバイスを受けましたが、それはコンセンサスのようです。簡単にするために、tar をスキップして ssh -C を使用します。

Perl スクリプト。ID を 1000 のグループに分割します。ID は、ハッシュ テーブルの source_id です。すべてのデータは、「HEADER」で区切られた単一の ssh 経由で送信されるため、適切なファイルに書き込まれます。これははるかに効率的です。

sub copy_tickserver_files {
my $self = shift;

my $cmd = 'cd tickserver/ ; ';

my $i = 1;

while ( my ($source_id, $dest_id) = each ( %{ $self->{id_translations} } ) ) {
    $cmd .= qq{ echo HEADER $source_id ; ./t_show $source_id ; };
    $i++;
    if ( $i % 1000 == 0 ) {
        $cmd = qq{ssh -C dba\@$self->{source_env}->{tickserver} " $cmd " | };
        $self->copy_tickserver_files_subset( $cmd );
        $cmd = 'cd tickserver/ ; ';
    }
}

$cmd = qq{ssh -C dba\@$self->{source_env}->{tickserver} " $cmd " | };
$self->copy_tickserver_files_subset( $cmd );

}

sub copy_tickserver_files_subset {
my $self = shift;
my $cmd = shift;

my $output = '';
open TICKS, $cmd;
while(<TICKS>) {
    if ( m{HEADER [ ] ([0-9]+) }mxs ) {
        my $id = $1;
        $output = "$self->{tmp_dir}/$id.ts";
        close TICKSOP;
        open TICKSOP, '>', $output;
        next;
    }
    next unless $output;
    print TICKSOP "$_";
}
close TICKS;
close TICKSOP;
}
于 2011-08-22T06:59:24.360 に答える
0

tar なしでもっとうまくやることができます:

#!/bin/bash
for id in `seq 1 1000`
do
    ./t_show $id
done | gzip

唯一の違いは、異なる ID 間の境界を取得できないことです。

それをスクリプトに入れてshow_me_the_ids、クライアントから言って実行します

shh user@source ./show_me_the_ids | gunzip

そして、そこにあります!

または、-Cフラグを指定して SSH 接続を圧縮し、gzip / gunzip の使用をまとめて削除することもできます。

あなたが本当にそれに興味があるならssh -Cgzip -9や他の圧縮プログラムを試すことができます。個人的には に賭けますlzma -9

于 2011-08-19T11:20:14.427 に答える
0

これは単純な bash スクリプトでは機能していないと思います。Archive::TARしかし、perl やその他のスクリプト言語のモジュールを見ることができます。

Perl モジュールにはadd_data、オンザフライで「ファイル」を作成し、ネットワーク経由でストリーミングするためにアーカイブに追加する機能があります。

ドキュメントは次の場所にあります。

于 2011-08-19T10:43:26.023 に答える