Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 高效传输控制台数据、tar&;不创建中间文件的gzip/bzip2_Linux_Bash_Gzip_Tar_Bzip2 - Fatal编程技术网

Linux 高效传输控制台数据、tar&;不创建中间文件的gzip/bzip2

Linux 高效传输控制台数据、tar&;不创建中间文件的gzip/bzip2,linux,bash,gzip,tar,bzip2,Linux,Bash,Gzip,Tar,Bzip2,Linux环境。因此,我们有一个程序't_show',当使用一个ID执行时,它会在控制台上写入该ID的价格数据。没有其他方法可以获得这些数据 我需要使用最小带宽、最小连接数在两台服务器之间复制IDs 1-10000的价格数据。在目标服务器上,数据将是每个id的单独文件,格式如下: <id>.dat 资料来源: scp user@source:dat.tar.gz ./ gunzip dat.tar.gz tar xvf dat.tar 也就是说,将每个输出写入自己的文件、压缩和t

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

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

<id>.dat
资料来源:

scp user@source:dat.tar.gz ./
gunzip dat.tar.gz
tar xvf dat.tar
也就是说,将每个输出写入自己的文件、压缩和tar、通过网络发送、提取

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

是否可以直接将控制台输出写入(压缩的)tar存档,而不创建中间文件?有没有更好的主意(可能是直接在网络上编写压缩数据,跳过tar)

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


感谢所有花时间帮忙的人。

我认为这不是一个简单的bash脚本。但是您可以看看perl或其他脚本语言的
Archive::TAR
模块

Perl模块有一个功能,可以动态创建一个“文件”,并将其添加到归档文件中,以便通过网络进行流式传输


文档可在此处找到:

您至少可以通过ssh连接
tar
填充内容:

tar -czf - inputfiles | ssh remotecomputer "tar -xzf -"
如何在没有中间文件的情况下填充归档文件,但我不知道


编辑:好的,我想您可以通过手动编写tar文件来完成。页眉是指定的,看起来并不太复杂,但这并不是我所认为的方便…

没有tar您可以做得更好:

#!/bin/bash
for id in `seq 1 1000`
do
    ./t_show $id
done | gzip
唯一的区别是,您将无法获得不同ID之间的边界

现在将其放入脚本中,说
向我显示\u id
,然后从客户端执行

shh user@source ./show_me_the_ids | gunzip
他们就在那里

或者,您可以指定
-C
标志来压缩SSH连接并同时删除gzip/gunzip使用

如果你真的喜欢它,你可以尝试
ssh-C
gzip-9
和其他压缩程序。
就我个人而言,我打赌lzma-9

你可以通过某种方式发送格式化的数据,并在接收器上解析它

发件人上的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
在传输过程中压缩数据

我会尝试以下方法:

(for ID in $(seq 1 10000); do echo $ID: $(/t_show $ID); done) | ssh user@destination "ImportscriptOrProgram" 
这将把“1:ValueOfID1”打印到standardout,后者通过ssh传输到目标主机,您可以在那里启动importscript或程序,从standardin读取行

谢谢大家

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

Perl脚本。将ID分成1000个组。id是哈希表中的源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;
}
子复制服务器文件{
我的$self=shift;
my$cmd='cd tickserver/;';
我的$i=1;
而(my($source\u id,$dest\u id)=每个(%{$self->{id\u translations}})){
$cmd.=qq{echo HEADER$source\u id;/t\u show$source\u id;};
$i++;
如果($i%1000==0){
$cmd=qq{ssh-cdba\@$self->{source_env}->{tickserver}“$cmd”|};
$self->copy_tickserver_files_subset($cmd);
$cmd='cd tickserver/;';
}
}
$cmd=qq{ssh-cdba\@$self->{source_env}->{tickserver}“$cmd”|};
$self->copy_tickserver_files_subset($cmd);
}
子副本\u服务器\u文件\u子集{
我的$self=shift;
我的$cmd=shift;
我的$output='';
打开滴答声,$cmd;
while(){
if(m{HEADER[]([0-9]+)}mxs){
my$id=$1;
$output=“$self->{tmp_dir}/$id.ts”;
关闭SOP;
打开“>”,$output;
下一个
}
下一步是产出;
打印“$”;
}
近蜱;
关闭SOP;
}

作为旁白,避免在回退中无用地使用Echo。在$files;中为id编写代码的惯用方法是
数据是否无法简单地作为单个大文本文件传输?听上去,你可以在标准输出上创建一个CSV文件,每个id都有“id”,“price”。谢谢。这就是我所采用的方法——跳过tar&gzip并通过单个连接解析数据。如果可能的话,我会把罐子寄出去
(for ID in $(seq 1 10000); do echo $ID: $(/t_show $ID); done) | ssh user@destination "ImportscriptOrProgram" 
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;
}