1

Linux 环境。所以,我们有这个程序 't_show',当使用 ID 执行时,会在控制台上写入该 ID 的价格数据。没有其他方法可以获取此数据。

我需要使用最小带宽、最小连接数在两台服务器之间复制 ID 1-10,000 的价格数据。在目标服务器上,数据将是每个 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

您至少可以tar通过 ssh 连接进行填充:

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

但是,我不知道如何在没有中间文件的情况下填充存档。

编辑:好的,我想你可以通过手动编写 tar 文件来做到这一点。此处指定了标头,似乎并不太复杂,但这不完全是我方便的想法...

于 2011-08-19T10:52:42.333 回答
0

我认为这不适用于普通的 bash 脚本。但是您可以查看Archive::TARperl 或其他脚本语言的模块。

Perl 模块具有add_data动态创建“文件”并将其添加到存档以在网络上流式传输的功能。

文档可在此处找到:

于 2011-08-19T10:43:26.023 回答
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 -C, gzip -9和其他压缩程序。我个人会打赌lzma -9

于 2011-08-19T11:20:14.427 回答
0

我会试试这个:

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

这会将“1:ValueOfID1”打印到标准输出,通过 ssh 传输到目标主机,您可以在其中启动导入脚本或程序,该程序从标准输入读取行。

高温高压

于 2011-08-19T12:23:56.277 回答
0

谢谢大家

我已经接受了“只需发送以某种方式格式化的数据并在接收器上解析它”的建议,这似乎是共识。为简单起见,跳过 tar 并使用 ssh -C。

Perl 脚本。将 id 分成 1000 个组。ID 是哈希表中的 source_id。所有数据都通过单个 ssh 发送,由“HEADER”分隔,因此它会写入相应的文件。这有效:

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 回答