29

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

pfiles `ls /proc` | less

并寻找“端口:80”,但如果有人有更好的解决方案,我会全力以赴!如果我可以在没有 root 的情况下寻找聆听过程,那就更好了。我对 shell 和 C 解决方案都持开放态度;下次出现这种情况时,我不介意随身携带一个小的自定义可执行文件。

更新:我说的是我不是管理员的 solaris 的通用安装(尽管我确实有超级用户访问权限),所以从免费软件磁盘安装东西不是一种选择。显然,两者都没有对 fuser、netstat 或其他工具使用特定于 Linux 的扩展。不幸的是,到目前为止,在所有进程上运行 pfiles 似乎是最好的解决方案。如果情况仍然如此,我可能会发布一个答案,其中包含一些比上面的剪辑更有效的代码。

4

11 回答 11

29

我在某个地方找到了这个脚本。我不记得在哪里,但它对我有用:

#!/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] 哪个进程绑定到给定端口?

于 2009-05-05T14:36:07.977 回答
10

这是一个单行:

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。

于 2013-04-24T20:25:23.270 回答
4

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); }
于 2012-03-14T14:24:34.513 回答
3
#!/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}"
于 2013-10-07T06:14:36.953 回答
3

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

如果您使用的是较低版本的 Solaris,那么 - 正如其他人所指出的那样 - Solaris 执行此操作的方式是某种围绕pfiles命令的脚本包装器。请注意,尽管该pfiles命令会暂停该过程一秒钟以检查它。对于 99.9% 的流程,这并不重要。不幸的是,我们有一个进程,如果它被pfiles命令击中,它将给出核心转储,因此我们对使用该命令有点谨慎。如果您在 99.9% 中,您的情况可能会完全不同,这意味着您可以安全地使用该pfiles命令。

于 2014-06-30T11:20:36.497 回答
2

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 帮我找到了。

于 2014-06-19T16:54:19.317 回答
1

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

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

于 2008-09-22T23:26:42.450 回答
1

我认为第一个答案是我编写自己的 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
于 2013-09-03T16:39:11.470 回答
0

这是一种间接的方法,但是您可以查看网站是否从端口 80 上运行的任何内容加载到您选择的 Web 浏览器上。或者您可以远程登录到端口 80,看看您是否收到可以为您提供线索的响应到该端口上正在运行的内容,您可以将其关闭。由于端口 80 是 http 流量的默认端口,因此默认情况下会在那里运行某种 http 服务器,但不能保证。

于 2008-10-08T13:49:56.620 回答
0

很可能是 sun 的管理服务器。它通常与 sun 的目录以及默认安装中的一些其他 webmin-ish 东西捆绑在一起

于 2008-09-18T09:26:32.513 回答
-3

如果您有权访问netstat,则可以做到这一点。

于 2008-09-18T09:25:54.573 回答