我正在尝试解析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没有启动而是它会给出这个错误并且永远不会启动。
答案 0 :(得分: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
命令的stdout传递给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脚本没有足够的时间来设置套接字。