Netstat 通過 php 函式 exec() 在 FreeBSD 上不起作用
在我的 php-app 中,我需要在埠 80 上連接的所有 IP 的列表。我選擇這樣做:
<?php $ips = exec("netstat -an |grep 'tcp\|udp' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c", $info); ?>
但它不適用於我的 VPS FreeBSD 伺服器。當我開始時
netstat -an
會出現一條通知並且輸出中沒有連接:netstat: kvm not available: /dev/mem: No such file or directory
我試圖添加
device mem
到 conf,但我有一個空的 /usr/src/sys。我到了需要重建核心的地步。))
netstat
當使用者是 root 時(從控制台)正常工作。我在類似的 CentOS 託管平台上沒有遇到過這樣的問題。
/dev/mem: No such file or directory
我嘗試過解決問題,mknod -m 660 /dev/mem c 1 1
但它呼叫了mknod: /dev/mem: Operation not permitted
我有以下使用者
pw showuser
owl:*:1000:1003:default:0:0:owl:/home/owl/data:/bin/csh root:*:0:0::0:0:Charlie &:/root:/bin/csh
摘要:
當我執行
netstat
時owl
- 它返回一個空的連接列表當我執行
netstat
時root
- 它返回通知netstat: kvm not available: /dev/mem: No such file or directory
和 IP有誰能夠幫助我?是否存在解決此任務的另一種方法?謝謝
我相信你
cut
的行為不像你期望的那樣,因為在netstat
’s 的輸出中,IP 和埠用點分隔,而不是冒號。當我在我管理的一些監獄中執行時,我也會得到一個
netstat: kvm not available: /dev/mem: No such file or directory
錯誤netstat -an
,但儘管有這個錯誤,我仍然從 netstat 得到預期的結果。我還沒有研究為什麼會發生這種情況,所以我傾向於認為這是一個紅鯡魚。就命令行而言,您可以通過將更多功能打包到 awk 腳本中來減少管道:
netstat -an | \ awk '/^(tcp|udp)/{ip=$5; sub(/.[0-9]+$/,"",ip); list[ip]++;} END{for(ip in list){printf("%7d %s\n",list[ip],ip)}}'
拆分為便於閱讀,這個 awk 腳本是:
# Only work on tcp/udp lines... /^(tcp|udp)/ { ip=$5; sub(/.[0-9]+$/,"",ip); list[ip]++; # Populate an array of counters-per-IP } # After data are gathered, print the results. END { for (ip in list) { printf("%7d %s\n",list[ip],ip); } }
但是由於您是在 PHP 中執行此操作,所以我會在 PHP 中進行更多的文本處理。
<?php # Gather our data... exec("netstat -an", $out); # Easy access to the output we want (for isset() below) $permit = array("udp4"=>1,"tcp4"=>1); foreach ($out as $line) { $a = preg_split("/[[:space:]]+/", $line); # Only work on tcp4/udp4 lines... if (isset($permit[$a[0]])) { # Populate an array of counters... $ip = substr($a[4], 0, strrpos($a[4],".")-1); $list[$ip]++; } } # And print the results. foreach ($list as $ip => $count) { printf("%7s\t%s\n", $count, $ip); }
這看起來像是更多的工作,但實際上它可能比生成管道集合更快。
請注意,您
sockstat
在 FreeBSD 中也有該命令,因此基於 Chris S 的建議:<?php exec("sockstat -4", $out); $permit = array("udp4"=>1,"tcp4"=>1); foreach ($out as $line) { $a = preg_split("/[[:space:]]+/", $line); if (isset($permit[$a[4]])) { preg_match("/^[^:]+/", $a[6], $ip); $list[$ip[0]]++; } } foreach ($list as $ip => $count) { printf("%7s\t%s\n", $count, $ip); }
更新:
我還發現了這個關於 kvm 錯誤的古老註釋。由於路由表資訊通常是可用的,因此您應該聯繫您的 VPS 提供商並了解他們是否故意限制您訪問此主機上的路由表數據。如果您不在監獄中,那麼我懷疑向 FreeBSD 郵件列表之一發帖會得到結果。irc.freenode.net 上還有一個##FreeBSD 頻道,知識淵博的人經常在那裡閒逛。