【发布时间】:2014-09-18 20:02:40
【问题描述】:
首先,我要感谢你们没有提供解决方案作为解决方案(尽管知道其他方法会很酷)。我正在设置 tg-master 项目(用于 cli 的电报)以供 check_mk 警报插件使用。我发现电报在标准输入/标准输出进程上运行,所以我认为“粘合”它会很酷,所以我用博客中的很多构建块编写了接下来的 2 段代码。他们已经工作了(我有时需要处理破损的管道),但我想知道是否可以分享一些专家的新想法。
正如您所见,我的代码依赖于一个 eval,它从生成的进程中读取一个 die,我知道这不是最好的方法。有什么建议么? :D
谢谢大家
服务器
use strict;
use IO::Socket::INET;
use IPC::Open2;
use POSIX;
our $pid;
use sigtrap qw/handler signal_handler normal-signals/;
sub signal_handler {
print "what a signal $!\nlets kill $pid\n";
kill 'SIGKILL', $pid;
#die "Caught a signal $!";
}
# auto-flush on socket
$| = 1;
# creating a listening socket
my $socket = new IO::Socket::INET(
LocalHost => '0.0.0.0',
LocalPort => '7777',
Proto => 'tcp',
Listen => 5,
Reuse => 1
);
die "cannot create socket $!\n" unless $socket;
print "server waiting for client connection on port 7777\n";
my ( $read_proc, $write_proc );
my ( $uid, $gid ) = ( getpwnam "nagios" )[ 2, 3 ];
POSIX::setgid($gid); # GID must be set before UID!
POSIX::setuid($uid);
$pid = open2( $read_proc, $write_proc, '/usr/bin/telegram' );
#flush first messages;
eval {
local $SIG{ALRM} = sub { die "Timeout" }; # alarm handler
alarm(1);
while (<$read_proc>) { }
};
while (1) {
my $client_socket = $socket->accept();
my $client_address = $client_socket->peerhost();
my $client_port = $client_socket->peerport();
print "connection from $client_address:$client_port\n";
# read until \n
my $data = "";
$data = $client_socket->getline();
# write to spawned process stdin the line we got on $data
print $write_proc $data;
$data = "";
eval {
local $SIG{ALRM} = sub { die "Timeout" }; # alarm handler
alarm(1);
while (<$read_proc>) {
$client_socket->send($_);
}
};
# notify client that response has been sent
shutdown( $client_socket, 1 );
}
$socket->close();
客户
echo "contact_list" | nc localhost 7777
或
echo "msg user#12345 NAGIOS ALERT ... etc" | nc localhost 7777
或
其他一些 perl 脚本 =)
【问题讨论】: