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的单独文件。
感谢任何花时间提供帮助的人。
答案 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 -C
,gzip -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;
}