我正在尝试使用Perl脚本中的sed命令。我必须从25GB的文件中获取最后一小时的数据,但是当我从终端运行相同的命令时,它工作正常,但是相同的命令在Perl脚本中不起作用。我正在使用的系统变量,导致我认为的问题,不知道如何处理:
my $sed_cmd = 'sed -n "/'.$last_hour.'/,\$p"';
my $outstr=`ssh $remote_addr $sed_cmd $dir/$remote_filename`;
上面的命令转换如下:sed -n "/15:12:24/,\$p"
和perl脚本无法正常工作。
但实际上这个命令正在终端:sed -n "/15:09:40/,\$p"
文件
唯一不同的是当我用ssh调用这个sed命令时我正在发生错误,否则它工作正常。你能否提出建议是什么问题
答案 0 :(得分:2)
您可以使用Net::OpenSSH。它会自动执行shell escaping:
my $ssh = Net::OpenSSH->new($remote_addr);
my $fh = $ssh->pipe_out('tac', "$dir/$remote_file");
my @out;
while (<$fh>) {
/$last_hour/ or last; # you may need to adjust this
# stop condition!
unshift @out, $_;
}
close($fh);
BTW,读取25Gb文件只是为了从末端获取一些行可能效率低下并产生可观的IO负载。也许您可以使用tac以相反的顺序读取文件行:
$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-agentpool0-41204139-0 36m 1% 682Mi 9%
k8s-agentpool0-41204139-1 33m 1% 732Mi 10%
k8s-agentpool0-41204139-10 36m 1% 690Mi 10%
[truncated]
答案 1 :(得分:1)
我认为你在使用反引号时遇到了一些引用地狱,你需要将ssh命令及其所有参数连接成一个字符串以发送给sh。我建议这样做,其中ssh命令的每个组件都是一个单独的词:
use autodie;
my @ssh_cmd = ('ssh', $remote_addr, 'sed', '-n', "/$last_hour/,\\\$p", "$dir/$remote_filename");
open my $pipe, '-|', @ssh_cmd;
my $outstr = join '', <$pipe>;
close $pipe;