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

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

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

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

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

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

谢谢你

ih99xse1

ih99xse11#

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

  1. use warnings;
  2. use strict;
  3. use feature 'say';
  4. while (my $line_in = <STDIN>) {
  5. chomp $line_in; # remove newline
  6. # ... # process
  7. say $line_in; # prints for demo
  8. }

现在使用命令

  1. ls -l . | script.pl

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

  1. use warnings;
  2. use strict;
  3. use feature 'say';
  4. my @cmd = qw(ls -l .);
  5. open(my $in, '-|', @cmd) or die "Can't pipe-open @cmd: $!";
  6. while (my $line_in = <$in>) {
  7. chomp $line_in;
  8. # ...
  9. say $line_in;
  10. }

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

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

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

展开查看全部
vzgqcmou

vzgqcmou2#

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

  1. mkfifo streamFile # make pipe file.
  2. exec 3<> streamFile # change descriptor to not block r/w
  3. # /* Here is if any line appears on streamFile it will pipe to Perl.
  4. # Whatever content appears on remote /var/log/messages pass to $line
  5. cat streamFile - | ssh user@server 'tail -f /var/log/messages' | while read line ; do
  6. echo $line | perl; # /* of course it fail, becasue perl expect differnt syntax. \
  7. # /* You can change another file which tail file for perl lang
  8. done

相关问题