31. Perl 脚本实战-psnetstat
psgrep 命令用于查询端口被那个进程占用, 主要特性:
- 支持通过端口号快速查询占用当前端口的进程
- 支持一次性查询多个端口号的占用进程
- 查询列表会展示netstat 命令 与ps 命令的综合信息
- 需要sudo 权限或root 用户执行
1. 用法示例
1.1 查询单个进程
$ psnetstat 7481
[1] tcp 0 0 127.0.0.1:7481 0.0.0.0:* LISTEN 31685/redis-server
zongf 31685 1311 0 13:37 ? 00:00:12 redis-server 127.0.0.1:7481 [cluster]
1.2 查询多个关键字
$ psnetstat 7481 7482
[1] tcp 0 0 127.0.0.1:7481 0.0.0.0:* LISTEN 31685/redis-server
zongf 31685 1311 0 13:37 ? 00:00:12 redis-server 127.0.0.1:7481 [cluster]
[2] tcp 0 0 127.0.0.1:7482 0.0.0.0:* LISTEN 31690/redis-server
zongf 31690 1311 0 13:37 ? 00:00:13 redis-server 127.0.0.1:7482 [cluster]
2. 命令源码
#!/usr/bin/perl
#Desc 查询本机监听端口号对应的服务
#Auth zonggf
#Date Tue Dec 13 19:15:00 CST 2016
use Term::ANSIColor qw(:constants);
$Term::ANSIColor::AUTORESET = 1;
#检查是否是查询帮助
sub check_help{
my $param = $ARGV[0];
if("-h" eq $param || "--help" eq $param){
print BOLD BLUE "Desc: "; print "查询占用指定端口的应用程序\n";
print BOLD BLUE "Args: "; print "一个或多个端口号,支持模糊查询\n";
print BOLD BLUE "Exam: "; print "psnetstat 22 8380\n";
print BOLD BLUE "Auth: "; print "zonggf\n";
print BOLD BLUE "Date: "; print "2016-12-22 18:57:16\n";
exit;
}
}
#格式化索引长度
#参数: 接收两个参数
# para1: 需要格式化的索引
# para2: 数组长度
#返回: [1 ]
sub fmt_idx{
return shift @_ if @_ < 2;
my ($str, $array_length) = @_;
my $length = length $array_length;
return sprintf "[%-${length}s] ", $str;
}
#################### 主程序 ####################
&check_help;
#进行端口号拼接
@patterns = @ARGV;
$ports = ":";
$ports .= shift @ARGV;
foreach (@ARGV){
$ports .="|:$_";
}
#如果参数不为空,则进行筛选
$netstat_cmd = 'sudo netstat -tlunp | grep LISTEN';
$netstat_cmd .= " | grep -E \"" . $ports ."\"" if defined $ports;
@lines = `$netstat_cmd`;
$lines_length = @lines;
foreach $idx (1 .. @lines){
$line = $lines[$idx-1];
#输出netstat 信息
printf BOLD GREEN &fmt_idx($idx, $lines_length) . $line;
#获取端口号
$idx = index ($line , '/');
$line = substr($line, 0, $idx);
($port,$net_pid) = (split(/\s+/,$line))[3,-1];
#查询占用端口号的进程
if($net_pid){
@ps_lines = `ps -ef | grep -v grep | grep -v /usr/bin/perl | grep $net_pid` if $net_pid;
foreach(@ps_lines){
$ps_pid = (split/\s+/, $_)[1];
print if $ps_pid eq $net_pid;
}
}
print "\n";
}
还没有评论,来说两句吧...