0

我正在尝试解析 rsyslog 日志。为此,我将所有日志发送到 socat,然后将它们发送到 Unix Domain Socket。该套接字是通过 perl 脚本创建的,该脚本正在侦听该套接字以解析日志。

rsyslog 向其发送所有日志的我的 bash 脚本是

if [ ! `pidof -x log_parser.pl` ] 
  then
./log_parser.pl & 1>&1
fi

if [ -S /tmp/sock ] 
then
/usr/bin/socat -t0 -T0   - UNIX-CONNECT:/tmp/sock 2>> /var/log/socat.log
fi

/tmp/sock是使用 perl 脚本创建log_parser.pl

use IO::Socket::UNIX;

sub socket_create {
    $socket_path = '/tmp/sock';
    unlink($socket_path);

    $listner = IO::Socket::UNIX->new(
       Type   => SOCK_STREAM,
       Local  => $socket_path,
       Listen => SOMAXCONN,
       Blocking => 0,
    )
       or die("Can't create server socket: $!\n");

   $socket = $listner->accept()
      or die("Can't accept connection: $!\n");
   }

   socket_create();
   while(1) {

   chomp($line=<$socket>);
   print "$line\n";
   }

我从 socat 得到这个错误是

2015/02/24 11:58:01 socat[4608] E connect(3, AF=1 "/tmp/sock", 11): Connection refused

我不是插座方面的冠军,所以我无法理解这是什么。请帮忙。提前致谢。

主要问题是,当我杀死我的 perl 脚本时,假设 bash 脚本会再次调用它并启动它。实际发生的是 sript 已启动但 socat 未启动,而是给出此错误并且永远不会启动。

4

1 回答 1

1

如果我在尝试使用 socat 之前不运行你的 perl 程序,我可以复制你的错误。这对我有用:

1)my_prog.pl:

use strict; 
use warnings; 
use 5.016;
use Data::Dumper;
use IO::Socket::UNIX;

my $socket_path = '/tmp/sock';
unlink $socket_path; 

my $socket = IO::Socket::UNIX->new(
    Local  => $socket_path,
    Type   => SOCK_STREAM,
    Listen => SOMAXCONN,
) or die "Couldn't create socket: $!";

say "Connected to $socket_path...";
my $CONN = $socket->accept()
    or die "Whoops! Failed to open a connection: $!";

{
    local $/ = undef;   #local -> restore previous value when the enclosing scope, delimited by the braces, is exited.
                        #Setting $/ to undef puts file reads in 'slurp mode' => whole file is considered one line.
    my $file = <$CONN>; #Read one line.
    print $file;
}`

2)$ perl my_prog.pl

3)socat -u -v GOPEN:./data.txt UNIX-CONNECT:/tmp/sock

-u 和 -v 选项不是必需的:

-u            Uses  unidirectional  mode.  The  first address is only used for
              reading, and the second address is only used for writing  (exam-
              ple).


-v            Writes the transferred data not only to  their  target  streams,
              but  also to stderr. The output format is text with some conver-
              sions for readability, and prefixed with "> " or "< " indicating
              flow directions.

4)你也可以这样做:

cat data.txt | socat STDIN UNIX-CONNECT:/tmp/sock

将命令的标准输出通过管道cat传输到 socat,然后将 STDIN 列为 socat 的文件之一。

回复评论:

这个 bash 脚本对我有用:

#!/usr/bin/env bash

echo 'bash script'

../pperl_programs/my_prog.pl &
sleep 1s

socat GOPEN:./data.txt UNIX-CONNECT:/tmp/sock

在 socat 尝试传输数据之前,perl 脚本似乎没有足够的时间来设置套接字。

于 2015-02-24T09:39:54.470 回答