将SSH流作为Perl脚本输入而不是物理文件

oknwwptz  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(195)

在Linux中有没有一种方法可以将终端/SSH流作为另一个程序的输入。
我可以让以下内容正常工作:

#!/bin/bash
FIFO="$1"
ps auwx | grep "[m]rLogger 192.168.10.10"
if [ $? -eq 0 ]; then
    exit
fi
while [ 1 ]
do
  /usr/bin/sshpass -p MrLoggertemp /usr/bin/ssh -t -t -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -l mrlogger 192.168.10.10 >> "$FIFO"
  echo "sshpass failed. restarting"
  sleep 1
done

..然后它会流到一个文件中
但是我想把这个流到一个Perl脚本中,我想做一些处理,然后加载到一个数据集中。
有没有办法在perl脚本中做如下像:

my $fifo_fh;
my $fifo_file = <The output of the stream above>
open($fifo_fh, "+< $fifo_file") or die

谢谢你

ih99xse1

ih99xse11#

我不知道你的命令“stream“是什么,也不知道你到底需要它做什么。
但是,Perl脚本可以通过多种方式充当过滤器。
如果你想将一个流通过管道传输到scirpt中,那么从STDIN(fd 0的perl句柄)读取它。

use warnings;
use strict;
use feature 'say';

while (my $line_in = <STDIN>) { 
    chomp $line_in;   # remove newline
    # ...             # process
    say $line_in;     # prints for demo
}

现在使用命令

ls -l . | script.pl

ls -l .的输出行在script.pl中处理(仅在上面打印)。
所以用你的例子代替cmd >> "$FIFO"cmd | script.pl并在脚本中写入(追加)到文件中,经过适当的处理。
如果您更愿意在脚本内部完成所有这些操作,一种基本方法是使用“pipe-open”

use warnings;
use strict;
use feature 'say';

my @cmd = qw(ls -l .);

open(my $in, '-|', @cmd) or die "Can't pipe-open @cmd: $!";

while (my $line_in = <$in>) { 
    chomp $line_in;
    # ...
    say $line_in;
}

当命令以列表(@cmd)的形式传递时,假设@cmd的第一个元素是要运行的程序,它被直接调用,而@cmd的其余部分则作为参数传递给它。这样就完全避免了shell,即使命令中有shell元字符。
但是如果命令是要使用shell的话,那么就把它写成一个字符串,或者把它当作"@cmd"来传递,其中引号将@cmd插入到一个字符串中,元素之间有空格。
然后,有一些库可以促进和改进这一点。它是最复杂的一种,但也是迄今为止功能最强大的一种,几乎可以让你的程序运行一个迷你shell。†
让我知道这是如何配合(或不)与您的用途,以便我们可以调整它,如果需要的话。
当一个循环条件被写为while (<$fh>)时,它通过<>操作符从文件句柄$fh读取的一行被赋值给一个无所不在的默认变量$_(如果我们显式地赋值给一个变量,就像我上面为了清楚起见所做的那样,那么交易就失败了,$_是未定义的)。
变量$_是许多其他运算符的默认值,包括chompsay
那么上面的例子可以写成

while (<$in>) { 
    chomp;
    ...      # process $_, which has the line of input
    say;
}

如果使用得当,这会导致代码非常精简和可读。但是如果我们最终需要在循环体中大量显式使用$_(不是所有的东西都默认使用它!),或者最终得到晦涩难懂的代码,那么请务必引入并使用一个好的词法变量。
†基本用途很简单。

vzgqcmou

vzgqcmou2#

另一种框架方法使用Linux命名管道。
通过远程服务器进行真实的通信。
https://en.wikipedia.org/wiki/Named_pipe

mkfifo streamFile    # make pipe file.
exec 3<> streamFile  # change descriptor to not block r/w

# /* Here is if any line appears on streamFile it will pipe to Perl.
#    Whatever content appears on remote /var/log/messages pass to $line

cat streamFile - | ssh user@server  'tail -f /var/log/messages' |  while read line ; do 
    echo $line | perl;   # /* of course it fail, becasue perl expect differnt syntax. \
                         # /* You can change another file which tail file for perl lang
done

相关问题