Linux 高效传输控制台数据、tar&;不创建中间文件的gzip/bzip2
Linux环境。因此,我们有一个程序't_show',当使用一个ID执行时,它会在控制台上写入该ID的价格数据。没有其他方法可以获得这些数据 我需要使用最小带宽、最小连接数在两台服务器之间复制IDs 1-10000的价格数据。在目标服务器上,数据将是每个id的单独文件,格式如下: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
<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;
}