所以我登录到Solaris机器,尝试启动Apache,发现已经有一个进程在监听端口80,但它不是Apache。我们的盒子没有安装 lsof,所以我无法用它来查询。我想我可以做:
pfiles `ls /proc` | less
并寻找“端口:80”,但如果有人有更好的解决方案,我洗耳恭听!如果我能在不成为 root 的情况下查找监听过程就更好了。我对 shell 和 C 解决方案都持开放态度;我不介意下次出现这种情况时随身携带一些自定义可执行文件。
更新:我正在谈论Solaris的通用安装,我不是管理员(尽管我确实有超级用户访问权限),所以从免费软件磁盘安装东西不是一个选项。显然,两者都没有使用 Linux 特定的 fusions 扩展、netstat 或其他工具。不幸的是,到目前为止,在all进程上运行pfiles似乎是最好的解决方案。如果情况仍然如此,我可能会发布一个答案,其中包含一些比上面的剪辑更有效的代码。
我在某处找到了这个脚本。我不记得在哪里,但它对我有用:
#!/bin/ksh
line='---------------------------------------------'
pids=$(/usr/bin/ps -ef | sed 1d | awk '{print $2}')
if [ $# -eq 0 ]; then
read ans?"Enter port you would like to know pid for: "
else
ans=$1
fi
for f in $pids
do
/usr/proc/bin/pfiles $f 2>/dev/null | /usr/xpg4/bin/grep -q "port: $ans"
if [ $? -eq 0 ]; then
echo $line
echo "Port: $ans is being used by PID:\c"
/usr/bin/ps -ef -o pid -o args | egrep -v "grep|pfiles" | grep $f
fi
done
exit 0
编辑:这是原始来源: [Solaris] 哪个进程绑定到给定端口?
这里有一句台词:
ps -ef| awk '{print $2}'| xargs -I '{}' sh -c 'echo examining process {}; pfiles {}| grep 80'
“回显检查进程 PID”将在每次搜索之前打印,因此一旦您看到引用端口 80 的输出,您就会知道哪个进程正在持有句柄。
或者使用:ps -ef| grep $USER|awk '{print $2}'| xargs -I '{}' sh -c 'echo examining process {}; pfiles {}| grep 80'
因为“pfiles”可能不喜欢你尝试访问其他用户的进程,当然除非你是 root。
Mavroprovato 的答案不仅仅报告监听端口。监听端口是没有对等点的套接字。以下 Perl 程序仅报告侦听端口。它适用于我的 SunOS 5.10。
#! /usr/bin/env perl
##
## Search the processes which are listening on the given port.
##
## For SunOS 5.10.
##
use strict;
use warnings;
die "Port missing" unless $#ARGV >= 0;
my $port = int($ARGV[0]);
die "Invalid port" unless $port > 0;
my @pids;
map { push @pids, $_ if $_ > 0; } map { int($_) } `ls /proc`;
foreach my $pid (@pids) {
open (PF, "pfiles $pid 2>/dev/null |")
|| warn "Can not read pfiles $pid";
$_ = <PF>;
my $fd;
my $type;
my $sockname;
my $peername;
my $report = sub {
if (defined $fd) {
if (defined $sockname && ! defined $peername) {
print "$pid $type $sockname\n"; } } };
while (<PF>) {
if (/^\s*(\d+):.*$/) {
&$report();
$fd = int ($1);
undef $type;
undef $sockname;
undef $peername; }
elsif (/(SOCK_DGRAM|SOCK_STREAM)/) { $type = $1; }
elsif (/sockname: AF_INET[6]? (.*) port: $port/) {
$sockname = $1; }
elsif (/peername: AF_INET/) { $peername = 1; } }
&$report();
close (PF); }
#!/usr/bin/bash
# This is a little script based on the "pfiles" solution that prints the PID and PORT.
pfiles `ls /proc` 2>/dev/null | awk "/^[^ \\t]/{smatch=\$0;next}/port:[ \\t]*${1}/{print smatch, \$0}{next}"
从 Solaris 11.2 开始,您确实可以使用
netstat
命令执行此操作。看看这里。 -u
开关就是您正在寻找的。
如果您使用的是较低版本的 Solaris,那么 - 正如其他人所指出的 - Solaris 执行此操作的方法是某种围绕
pfiles
命令的脚本包装器。请注意,pfiles
命令会暂时停止该过程以进行检查。对于 99.9% 的进程来说,这并不重要。不幸的是,我们有一个进程,如果使用 pfiles
命令命中,它会提供核心转储,因此我们对使用该命令有点谨慎。如果您是 99.9%,您的情况可能会完全不同,这意味着您可以安全地使用 pfiles
命令。
Solaris 上的 netstat 不会告诉您这一点,旧版本的 lsof 也不会告诉您这一点,但如果您下载并构建/安装较新版本的 lsof,这可以告诉您这一点。
$ lsof -v
lsof version information:
revision: 4.85
latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
configuration info: 64 bit kernel
constructed: Fri Mar 7 10:32:54 GMT 2014
constructed by and on: user@hostname
compiler: gcc
compiler version: 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
8<- - - - ***SNIP*** - - -
这样您就可以使用 -i 选项:
$ lsof -i:22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 521 root 3u IPv6 0xffffffff89c67580 0t0 TCP *:ssh (LISTEN)
sshd 5090 root 3u IPv6 0xffffffffa8668580 0t322598 TCP host.domain.com:ssh->21.43.65.87:52364 (ESTABLISHED)
sshd 5091 johngh 4u IPv6 0xffffffffa8668580 0t322598 TCP host.domain.com:ssh->21.43.65.87:52364 (ESTABLISHED)
这准确地显示了您所要求的内容。
我昨天遇到了一个问题,Jetty (Java) 进程崩溃了,它的 /proc/[PID] 目录中只留下了 2 个文件(psinfo 和用法)。
pfiles 找不到进程(因为所需的日期不存在)
lsof 帮我找到了。
您可能不想这样做,但最好的选择是获取 sunfreeware CD 并安装 lsof。
除此之外,是的,你可以使用 shell 脚本在 /proc 中卑躬屈膝。
我认为第一个答案是最好的 我编写了自己的 shell 脚本来发展这个想法:
#!/bin/sh
if [ $# -ne 1 ]
then
echo "Sintaxis:\n\t"
echo " $0 {port to search in process }"
exit
else
MYPORT=$1
for i in `ls /proc`
do
pfiles $i | grep port | grep "port: $MYPORT" > /dev/null
if [ $? -eq 0 ]
then
echo " Port $MYPORT founded in $i proccess !!!\n\n"
echo "Details\n\t"
pfiles $i | grep port | grep "port: $MYPORT"
echo "\n\t"
echo "Process detail: \n\t"
ps -ef | grep $i | grep -v grep
fi
done
fi
很可能是sun的管理服务器.. 它通常与 sun 的目录和默认安装中的其他一些 webmin 风格的东西捆绑在一起
这是一种间接方法,但您可以查看某个网站是否从端口 80 上运行的任何内容加载到您选择的 Web 浏览器上。或者您可以 telnet 到端口 80,看看是否收到能为您提供线索的响应至于该端口上正在运行什么,您可以将其关闭。由于端口 80 是 http 流量的默认端口,因此默认情况下可能有某种 http 服务器在该端口运行,但不能保证。
使用下面的脚本来识别端口号和相关进程ID:
# sh port_scan_pid.sh 22
#!/bin/bash
Hostnames=`uname -n | cut -d. -f1`
port=$1
OS=`uname -s`
printf "+----------+--------+-------+-------+\n"
printf "| %-8s | %-6s | %-5s | %-5s |\n" "HostName" "PID" "PORT" "OS"
printf "+----------+--------+-------+-------+\n"
for Process_id in `ls /proc`
do
pfiles $Process_id 2>/dev/null | grep AF_INET | grep -w "$port" > /dev/null 2>&1
if [ $? -eq 0 ]; then
#echo "$Hostnames | $Process_id | $port | $OS"
printf "| %-8s | %-6s | %-5s | %-4s |\n" "$Hostnames" "$Process_id" "$port" "$OS"
else
echo "$Hostnames | $OS | $port no PID found" > /dev/null 2>&1
fi
done
printf "+----------+--------+-------+-------+\n"
如果您可以访问
netstat
,那就可以做到这一点。