高效传输控制台数据,tar& gzip / bzip2没有创建中间文件

时间:2011-08-19 10:37:41

标签: linux bash gzip tar bzip2

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

我需要使用最小带宽,最小连接数复制两台服务器之间的ID为1-10,000的价格数据。在目标服务器上,数据将是每个ID的单独文件,格式为:

<id>.dat

这样的事情将是冗长的解决方案:

DEST:

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

也就是说,将每个输出写入自己的文件,压缩&amp; tar,通过网络发送,提取。

我的问题是我需要为每个id创建一个新文件。这占用了大量的空间,并且不能很好地扩展。

是否可以在不创建中间文件的情况下将控制台输出直接写入(压缩)tar存档?任何更好的想法(可能直接在网络上编写压缩数据,跳过tar)?

tar存档需要像我在目标服务器上所说的那样提取每个ID的单独文件。

感谢任何花时间提供帮助的人。

6 个答案:

答案 0 :(得分: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在传输过程中压缩数据

答案 1 :(得分:1)

你可以通过ssh连接至少tar

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

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

编辑:好的,我想你可以通过手动编写tar文件来实现。标题被指定为here并且看起来并不太复杂,但这并不是我想象的方便......

答案 2 :(得分:0)

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

Perl模块有一个函数add_data可以动态创建一个“文件”并将其添加到存档中,以便对网络进行流式处理。

文档可在此处找到:

答案 3 :(得分:0)

没有焦油你可以做得更好:

#!/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

答案 4 :(得分:0)

我会试试这个:

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

这会将“1:ValueOfID1”打印到standardout,它通过ssh传输到目标主机,在那里你可以启动你的importscript或程序,它从standardin读取行。

HTH

答案 5 :(得分:0)

全部谢谢

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

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

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;
}