在Solaris上,哪个进程正在监听某个端口?

时间:2022-04-30 16:24:42

So I log into a Solaris box, try to start Apache, and find that there is already a process listening on port 80, and it's not Apache. Our boxes don't have lsof installed, so I can't query with that. I guess I could do:

因此,我登录到一个Solaris框,尝试启动Apache,发现已经有一个进程监听端口80,而且它不是Apache。我们的盒子没有安装lsof,所以我无法查询。我想我能做到:

pfiles `ls /proc` | less

and look for "port: 80", but if anyone has a better solution, I'm all ears! Even better if I can look for the listening process without being root. I'm open to both shell and C solutions; I wouldn't mind having a little custom executable to carry with me for the next time this comes up.

寻找“端口:80”,但如果有人有更好的解决方案,我洗耳恭听!如果我能在没有根的情况下寻找听力过程,那就更好了。我对shell和C解都开放;我不介意有一个小的自定义的可执行文件随身携带,以便下次它出现。

Updated: I'm talking about generic installs of solaris for which I am not the administrator (although I do have superuser access), so installing things from the freeware disk isn't an option. Obviously neither are using Linux-specific extensions to fuser, netstat, or other tools. So far running pfiles on all processes seems to be the best solution, unfortunately. If that remains the case, I'll probably post an answer with some slightly more efficient code that the clip above.

更新:我说的是solaris的通用安装,我不是管理员(尽管我有超级用户访问权限),所以从免费软件磁盘安装东西不是一个选项。显然,它们都没有对fuser、netstat或其他工具使用特定于linux的扩展。不幸的是,到目前为止,在所有进程上运行pfile似乎是最好的解决方案。如果仍然是这样的话,我可能会用一些稍微更有效的代码来回答这个问题。

11 个解决方案

#1


27  

I found this script somewhere. I don't remember where, but it works for me:

我在什么地方找到这个脚本的。我不记得在哪里,但它对我很有用:

#!/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

Edit: Here is the original source: [Solaris] Which process is bound to a given port ?

编辑:这是原始的源代码:[Solaris]哪个进程被绑定到一个给定的端口?

#2


8  

Here's a one-liner:

这里有一个小笑话:

ps -ef| awk '{print $2}'| xargs -I '{}' sh -c 'echo examining process {}; pfiles {}| grep 80'

'echo examining process PID' will be printed before each search, so once you see an output referencing port 80, you'll know which process is holding the handle.

在每次搜索之前都要打印“echo检查过程PID”,因此,一旦您看到一个引用端口80的输出,您就会知道哪个进程掌握了该句柄。

Alternatively use:

ps -ef| grep $USER|awk '{print $2}'| xargs -I '{}' sh -c 'echo examining process {}; pfiles {}| grep 80'

Since 'pfiles' might not like that you're trying to access other user's processes, unless you're root of course.

因为“pfiles”可能不喜欢你试图访问其他用户的进程,除非你是root用户。

#3


4  

Mavroprovato's answer reports more than only the listening ports. Listening ports are sockets without a peer. The following Perl program reports only the listening ports. It works for me on SunOS 5.10.

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); }

#4


3  

From Solaris 11.2 onwards you can indeed do this with the netstat command. Have a look here. The -u switch is what you are looking for.

从Solaris 11.2开始,您确实可以使用netstat命令进行此操作。看看这里。u开关就是你要找的。

If you are on a lower version of Solaris then - as others have pointed out - the Solaris way of doing this is some kind of script wrapper around pfiles command. Beware though that pfiles command halts the process for a split second in order to inspect it. For 99.9% of processes this is unimportant. Unfortunately we have a process that will give a core dump if it is hit with a pfiles command so we are a bit cautious about using the command. Your situation may be totally different if you are in the 99.9%, meaning you can safely use the pfiles command.

如果您使用的是Solaris的较低版本,那么—正如其他人所指出的—实现此目的的Solaris方法是某种围绕pfiles命令的脚本包装器。注意,pfiles命令将进程暂停一秒钟,以便检查它。对于99.9%的流程来说,这并不重要。不幸的是,我们有一个进程,如果它被pfiles命令击中,就会给出一个核心转储,所以我们在使用该命令时要谨慎一些。如果您在99.9%,您的情况可能完全不同,这意味着您可以安全地使用pfiles命令。

#5


2  

#!/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}"

#6


2  

netstat on Solaris will not tell you this, nor will older versions of lsof, but if you download and build/install a newer version of lsof, this can tell you that.

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*** - - -

With this you can use the -i option:

有了这个,你可以使用-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)

Which shows you exactly what you're asking for.

这正好说明了你要的是什么。

I had a problem yesterday with a crashed Jetty (Java) process, which only left 2 files in its /proc/[PID] directory (psinfo & usage).

昨天我在Jetty (Java)进程中遇到了一个问题,它只在/proc/[PID]目录(psinfo & usage)中保留了两个文件。

pfiles failed to find the process (because the date it needed was not there)

pfiles无法找到进程(因为它需要的日期不存在)

lsof found it for me.

我找到了。

#7


1  

You might not want to, but your best bet is to grab the sunfreeware CD and install lsof.

您可能不想这样做,但是您最好的选择是获取sunfreeware CD并安装lsof。

Other than that, yes you can grovel around in /proc with a shell script.

除此之外,是的,您可以使用shell脚本在/proc中摸索。

#8


0  

Most probly sun's administrative server.. It's usually bundled along with sun's directory and a few other webmin-ish stuff that is in the default installation

最可靠的sun的管理服务器。它通常与sun的目录以及默认安装中的其他一些类似webmin的东西捆绑在一起

#9


0  

This is sort of an indirect approach, but you could see if a website loads on your web browser of choice from whatever is running on port 80. Or you could telnet to port 80 and see if you get a response that gives you a clue as to what is running on that port and you can go shut it down. Since port 80 is the default port for http traffic chances are there is some sort of http server running there by default, but there's no guarantee.

这是一种间接的方法,但是您可以看到网站在您的web浏览器上是否从端口80上运行的任何东西加载。或者你也可以telnet到80端口,看看你是否得到了一个响应,这个响应给了你一个关于在那个端口上运行的东西的线索,你可以关闭它。由于端口80是http流量的默认端口,所以默认情况下有某种http服务器在那里运行,但是没有保证。

#10


0  

I think the first answer is the best I wrote my own shell script developing this idea :

我认为第一个答案是我自己编写的最好的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

#11


-3  

If you have access to netstat, that can do precisely that.

如果您可以访问netstat,那么可以做到这一点。

#1


27  

I found this script somewhere. I don't remember where, but it works for me:

我在什么地方找到这个脚本的。我不记得在哪里,但它对我很有用:

#!/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

Edit: Here is the original source: [Solaris] Which process is bound to a given port ?

编辑:这是原始的源代码:[Solaris]哪个进程被绑定到一个给定的端口?

#2


8  

Here's a one-liner:

这里有一个小笑话:

ps -ef| awk '{print $2}'| xargs -I '{}' sh -c 'echo examining process {}; pfiles {}| grep 80'

'echo examining process PID' will be printed before each search, so once you see an output referencing port 80, you'll know which process is holding the handle.

在每次搜索之前都要打印“echo检查过程PID”,因此,一旦您看到一个引用端口80的输出,您就会知道哪个进程掌握了该句柄。

Alternatively use:

ps -ef| grep $USER|awk '{print $2}'| xargs -I '{}' sh -c 'echo examining process {}; pfiles {}| grep 80'

Since 'pfiles' might not like that you're trying to access other user's processes, unless you're root of course.

因为“pfiles”可能不喜欢你试图访问其他用户的进程,除非你是root用户。

#3


4  

Mavroprovato's answer reports more than only the listening ports. Listening ports are sockets without a peer. The following Perl program reports only the listening ports. It works for me on SunOS 5.10.

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); }

#4


3  

From Solaris 11.2 onwards you can indeed do this with the netstat command. Have a look here. The -u switch is what you are looking for.

从Solaris 11.2开始,您确实可以使用netstat命令进行此操作。看看这里。u开关就是你要找的。

If you are on a lower version of Solaris then - as others have pointed out - the Solaris way of doing this is some kind of script wrapper around pfiles command. Beware though that pfiles command halts the process for a split second in order to inspect it. For 99.9% of processes this is unimportant. Unfortunately we have a process that will give a core dump if it is hit with a pfiles command so we are a bit cautious about using the command. Your situation may be totally different if you are in the 99.9%, meaning you can safely use the pfiles command.

如果您使用的是Solaris的较低版本,那么—正如其他人所指出的—实现此目的的Solaris方法是某种围绕pfiles命令的脚本包装器。注意,pfiles命令将进程暂停一秒钟,以便检查它。对于99.9%的流程来说,这并不重要。不幸的是,我们有一个进程,如果它被pfiles命令击中,就会给出一个核心转储,所以我们在使用该命令时要谨慎一些。如果您在99.9%,您的情况可能完全不同,这意味着您可以安全地使用pfiles命令。

#5


2  

#!/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}"

#6


2  

netstat on Solaris will not tell you this, nor will older versions of lsof, but if you download and build/install a newer version of lsof, this can tell you that.

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*** - - -

With this you can use the -i option:

有了这个,你可以使用-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)

Which shows you exactly what you're asking for.

这正好说明了你要的是什么。

I had a problem yesterday with a crashed Jetty (Java) process, which only left 2 files in its /proc/[PID] directory (psinfo & usage).

昨天我在Jetty (Java)进程中遇到了一个问题,它只在/proc/[PID]目录(psinfo & usage)中保留了两个文件。

pfiles failed to find the process (because the date it needed was not there)

pfiles无法找到进程(因为它需要的日期不存在)

lsof found it for me.

我找到了。

#7


1  

You might not want to, but your best bet is to grab the sunfreeware CD and install lsof.

您可能不想这样做,但是您最好的选择是获取sunfreeware CD并安装lsof。

Other than that, yes you can grovel around in /proc with a shell script.

除此之外,是的,您可以使用shell脚本在/proc中摸索。

#8


0  

Most probly sun's administrative server.. It's usually bundled along with sun's directory and a few other webmin-ish stuff that is in the default installation

最可靠的sun的管理服务器。它通常与sun的目录以及默认安装中的其他一些类似webmin的东西捆绑在一起

#9


0  

This is sort of an indirect approach, but you could see if a website loads on your web browser of choice from whatever is running on port 80. Or you could telnet to port 80 and see if you get a response that gives you a clue as to what is running on that port and you can go shut it down. Since port 80 is the default port for http traffic chances are there is some sort of http server running there by default, but there's no guarantee.

这是一种间接的方法,但是您可以看到网站在您的web浏览器上是否从端口80上运行的任何东西加载。或者你也可以telnet到80端口,看看你是否得到了一个响应,这个响应给了你一个关于在那个端口上运行的东西的线索,你可以关闭它。由于端口80是http流量的默认端口,所以默认情况下有某种http服务器在那里运行,但是没有保证。

#10


0  

I think the first answer is the best I wrote my own shell script developing this idea :

我认为第一个答案是我自己编写的最好的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

#11


-3  

If you have access to netstat, that can do precisely that.

如果您可以访问netstat,那么可以做到这一点。