使用Net :: OpenSSH尾部的消息文件和grep

时间:2018-01-09 16:34:35

标签: linux perl ssh

我正在使用Net::OpenSSH

my $ssh = Net::OpenSSH->new("$linux_machine_host")

使用SSH对象,几个命令多次执行N小时。

有时我需要在var/adm/message文件中查找任何错误消息,例如 Timeout

我的建议

$ssh->capture2("echo START >> /var/adm/messages");
$ssh->capture2("some command which will be run in background for n hours");
$ssh->capture2("echo END >> /var/adm/messages");

然后阅读STARTEND之间的所有行,并阅读grep以获取所需的错误消息。

$ssh->capture2("grep -A 100000 "START" /var/adm/messages | grep -B 100000 END");`

如果不将STARTEND写入消息文件,我可以在某个时间点tail var/adm/message文件并捕获之后出现的任何新消息。

是否有任何Net::OpenSSH方法可以捕获新行并将其写入文件?

1 个答案:

答案 0 :(得分:1)

您可以通过SFTP阅读messages文件(请参阅Net::SFTP::Foreign):

# untested!
use Net::SFTP::Foreign::Constants qw(:flags);

...
my $sftp = $ssh->sftp;
# open the messages file creating it if it doesn't exist
# and move to the end:
my $fh = $sftp->open("/var/adm/messages",
                     SSH2_FXF_READ|SSH2_FXF_CREAT)
    or die $sftp->error;
seek($fh, 0, 2);

$ssh->capture2("some command which...");

# look for the size of /var/adm/messages now so that we
# can ignore any lines that may be appended while we are
# reading it:
my $end = (stat $fh)[7];

# and finally read any lines added since we opened it:
my @msg;
while (1) {
    my $pos = tell $fh;
    last if $pos < 0 or $pos >= $end;
    my $line = <$fh>;
    last unless defined $line;
    push @msg, $line;
}

请注意,您没有考虑可能会轮换消息文件。处理需要更复杂的方法。