我必须在 php 脚本中接收 snmptraps,因此我所做的是:
snmptrapd配置文件
traphandle 1.3.6.1.4.1.3.1.1 /usr/home/user/trap/l.php
php 目录
#!/usr/local/bin/php
<?php
$flow = fopen("php://stderr","r");
while(!feof($flow)){
file_put_contents("out",fread($flow,1024)."\n", FILE_APPEND);
}
?>
然后我像这样启动 snmptrapd:
snmptrapd -Le -f
并生成如下陷阱:
snmptrap -v 1 -c public localhost '' localhost 6 1 ''
snmptrapd 给了我这样的输出
2012-01-16 14:38:49 127.0.0.1(via UDP: [127.0.0.1]:11478->[0.0.0.0]:0) TRAP, SNMP v1, community public
SNMPv2-SMI::enterprises.3.1.1 Enterprise Specific Trap (1) Uptime: 70 days, 1:03:57.00
看起来似乎有效...但问题是php 目录没有执行,或者 stderr 中没有任何内容——我无法意识到。
请问我的错误在哪里?
答案1
php://stderr
不是可以读取的流。它是STDERR
PHP 进程本身的管道,是只写的。
您需要通过 访问数据STDIN
。而不是使用php://
包装器访问 STDIO 流,因为众所周知,包装器存在缺陷(请参阅手动的) 应使用特殊常量STDOUT
、STDERR
和STDIN
。例如,我可能会像这样编写您的 PHP 脚本:
#!/usr/local/bin/php
<?php
// The file we will be writing to. It's best to specify a full path, to avoid
// any confusion over the current working directory
$outFile = '/var/myuser/snmp.out';
// First, we'll open our outfile...
if (!$ofp = fopen($outFile, 'a')) exit("Oh No! I couldn't open my out file!");
// ...and write the current timestamp to it, so we are certain the script was
// invoked. You can remove this if you want, once you are sure it is working
fwrite($ofp, "Process started at ".date('Y-m-d H:i:s')."\n");
// Next we'll write all the trap data to the file
// We could use stream_copy_to_stream() for this, but I don't know if it is
// available on your server so I won't do it here
fwrite($ofp,"Data:\n");
while (!feof(STDIN)) {
fwrite($ofp, fread(STDIN, 1024)."\n");
}
fwrite($ofp,"End Data\n");
// We don't actually need a closing PHP tag and in many cases it is better
// to omit it, to avoid unexpected whitespace being output.