如何在Linux中查找进程ID打开的端口?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/942824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:22:28  来源:igfitidea点击:

How to find ports opened by process ID in Linux?

linuxbashnetworking

提问by omg

Suppose the PID of the process is already known

假设进程的PID是已知的

回答by lothar

You can use the netstatcommand line tool with the -pcommand line argument:

您可以使用带有命令行参数的netstat命令行工具-p

-p(Linux):

Process: Show which processes are using which sockets (similar to -bunder Windows). You must be root to do this.

-p(Linux):

进程:显示哪些进程正在使用哪些套接字(类似于-bWindows 下)。您必须是 root 才能执行此操作。

The example sectiongives this example:

例子部分给出了这样的例子:

To display all ports open by a process with id $PID:

netstat -ao | grep '\b'$PID'\b'

要显示由 id 进程打开的所有端口$PID

netstat -ao | grep '\b'$PID'\b'

回答by daniel

As a side note, netstat -ao will read the /proc/PID/tcp etc to see the ports opened by the process. This means that its reading information supplied by the system (the linux KERNEL), and is in no way directly looking on the network interface or other means. Same goes for lsof.

作为旁注,netstat -ao 将读取 /proc/ PID/tcp 等以查看进程打开的端口。这意味着它的读取信息是由系统(linux KERNEL)提供的,绝不是直接在网络接口或其他方式上查看的。lsof 也是如此。

If you are doing this as a security measure, you failed. You should never (NEVER EVER) trust the output of netstat, even if you are 100% sure you are in fact running a real netstat program (as opposed to a trojaned version) or any other program that reads the /proc filesystem. Some people seem to think that netstat, ls, ps or any other of the standard unix tools do some sort of magic and poll information from the sources, the truth is all of them rely on the /proc filesystem to get all of their data, which can be easily subverted by a rootkit or hypervisor.

如果你这样做是为了安全措施,你就失败了。你永远不应该(永远永远)相信 netstat 的输出,即使你 100% 确定你实际上正在运行一个真正的 netstat 程序(而不是木马版本)或任何其他读取 /proc 文件系统的程序。有些人似乎认为 netstat、ls、ps 或任何其他标准 unix 工具会从源头做某种魔法和轮询信息,事实是它们都依赖 /proc 文件系统来获取所有数据,可以很容易地被 rootkit 或虚拟机管理程序破坏。

回答by Jorge Zuanon

netstat --all --program | grep '3265'
  • --allshow listening and non-listening sockets.
  • --programshow the PID and name of the program to which socket belongs.
  • --all显示监听和非监听套接字。
  • --program显示socket所属程序的PID和名称。

You could also use a port scanner such as Nmap.

您也可以使用端口扫描器,例如 Nmap。

回答by abrusa

In some embedded devices or with old version of Linux, the problem is netstatdo not have --processor -poptions available.

在某些嵌入式设备或旧版本的 Linux 中,问题是netstat没有--process-p选项可用。

The following script shows process with its IP and port, you must be root.

以下脚本显示进程及其 IP 和端口,您必须是 root。

#!/bin/bash

for protocol in tcp udp ; 
do 
    #echo "protocol $protocol" ; 
    for ipportinode in `cat /proc/net/tcp | awk '/.*:.*:.*/{print "|""|" ;}'` ; 
    do 
        #echo "#ipportinode=$ipportinode"
        inode=`echo "$ipportinode" | cut -d"|" -f3` ;
        if [ "#$inode" = "#" ] ; then continue ; fi 
        lspid=`ls -l /proc/*/fd/* 2>/dev/null | grep "socket:\[$inode\]" 2>/dev/null` ; 
        pid=`echo "lspid=$lspid" | awk 'BEGIN{FS="/"} /socket/{print }'` ;
        if [ "#$pid" = "#" ] ; then continue ; fi
        exefile=`ls -l /proc/$pid/exe | awk 'BEGIN{FS=" -> "}/->/{print ;}'`
        #echo "$protocol|$pid|$ipportinode" 
        echo "$protocol|$pid|$ipportinode|$exefile" | awk '
            BEGIN{FS="|"}
            function iphex2dec(ipport){ 
                ret=sprintf("%d.%d.%d.%d:    %d","0x"substr(ipport,1,2),"0x"substr(ipport,3,2),
                "0x"substr(ipport,5,2),"0x"substr(ipport,7,2),"0x"substr(ipport,10,4)) ;
                if( ret == "0.0.0.0:0" ) #compatibility others awk versions 
                {
                    ret=        strtonum("0x"substr(ipport,1,2)) ;
                    ret=ret "." strtonum("0x"substr(ipport,3,2)) ;
                    ret=ret "." strtonum("0x"substr(ipport,5,2)) ;
                    ret=ret "." strtonum("0x"substr(ipport,7,2)) ;
                    ret=ret ":" strtonum("0x"substr(ipport,10)) ;
                }
                return ret ;
            }
            { 
            print " pid:"" local="iphex2dec()" remote="iphex2dec()" inode:"" exe="  ;  
            }
            ' ; 
        #ls -l /proc/$pid/exe ; 
    done ; 
done

The output is like:

输出是这样的:

tcp pid:1454 local=1.0.0.127:5939 remote=0.0.0.0:0 inode:13955 exe=/opt/teamviewer/tv_bin/teamviewerd
tcp pid:1468 local=1.1.0.127:53 remote=0.0.0.0:0 inode:12757 exe=/usr/sbin/dnsmasq
tcp pid:1292 local=0.0.0.0:22 remote=0.0.0.0:0 inode:12599 exe=/usr/sbin/sshd
tcp pid:4361 local=1.0.0.127:631 remote=0.0.0.0:0 inode:30576 exe=/usr/sbin/cupsd
tcp pid:1375 local=1.0.0.127:5432 remote=0.0.0.0:0 inode:12650 exe=/usr/lib/postgresql/9.3/bin/postgres

回答by Waveter

You can use the command below:

您可以使用以下命令:

lsof -i -P |grep pid

回答by wof

I've added IPv6 support and made a few fixes. Additionally on my system the octets of the IP address are reversed. Dependencies are only to posix shell, awk and cut.

我添加了 IPv6 支持并做了一些修复。此外,在我的系统上,IP 地址的八位字节是颠倒的。依赖项仅对 posix shell、awk 和 cut。

My Version can be found on Github

我的版本可以在Github上找到

#!/bin/sh


# prints all open ports from /proc/net/* 
#
# for pretty output (if available) start with 
# ./linux-get-programm-to-port.sh | column -t -s $'\t' 


#set -x

ip4hex2dec () {
    local ip4_1octet="0x${1%???????????}"

    local ip4_2octet="${1%?????????}"
    ip4_2octet="0x${ip4_2octet#??}"

    local ip4_3octet="${1%???????}"
    ip4_3octet="0x${ip4_3octet#????}"

    local ip4_4octet="${1%?????}"
    ip4_4octet="0x${ip4_4octet#??????}"

    local ip4_port="0x${1##*:}"

    # if not used inverse
    #printf "%d.%d.%d.%d:%d" "$ip4_1octet" "$ip4_2octet" "$ip4_3octet" "$ip4_4octet" "$ip4_port"
    printf "%d.%d.%d.%d:%d" "$ip4_4octet" "$ip4_3octet" "$ip4_2octet" "$ip4_1octet" "$ip4_port"
}


# reoder bytes, byte4 is byte1 byte2 is byte3 ...
reorderByte(){
    if [ ${#1} -ne 8 ]; then echo "missuse of function reorderByte"; exit; fi

    local byte1="${1%??????}"

    local byte2="${1%????}"
    byte2="${byte2#??}"

    local byte3="${1%??}"
    byte3="${byte3#????}"

    local byte4="${1#??????}"

    echo "$byte4$byte3:$byte2$byte1"
}

# on normal intel platform the byte order of the ipv6 address in /proc/net/*6 has to be reordered.
ip6hex2dec(){
    local ip_str="${1%%:*}"
    local ip6_port="0x${1##*:}"
    local ipv6="$(reorderByte ${ip_str%????????????????????????})"
    local shiftmask="${ip_str%????????????????}"
    ipv6="$ipv6:$(reorderByte ${shiftmask#????????})"
    shiftmask="${ip_str%????????}"
    ipv6="$ipv6:$(reorderByte ${shiftmask#????????????????})"
    ipv6="$ipv6:$(reorderByte ${ip_str#????????????????????????})"
    ipv6=$(echo $ipv6 | awk '{ gsub(/(:0{1,3}|^0{1,3})/, ":"); sub(/(:0)+:/, "::");print}')
    printf "%s:%d" "$ipv6" "$ip6_port"
}

for protocol in tcp tcp6 udp udp6 raw raw6; 
do 
    #echo "protocol $protocol" ; 
    for ipportinode in `cat /proc/net/$protocol | awk '/.*:.*:.*/{print "|""|" ;}'` ; 
    do 
        #echo "#ipportinode=$ipportinode"
        inode=${ipportinode##*|}
        if [ "#$inode" = "#" ] ; then continue ; fi 

        lspid=`ls -l /proc/*/fd/* 2>/dev/null | grep "socket:\[$inode\]" 2>/dev/null` ; 
        pids=`echo "$lspid" | awk 'BEGIN{FS="/"} /socket/{pids[]} END{for (pid in pids) {print pid;}}'` ;  # removes duplicats for this pid
        #echo "#lspid:$lspid  #pids:$pids"

        for pid in $pids; do
            if [ "#$pid" = "#" ] ; then continue ; fi
            exefile=`ls -l /proc/$pid/exe | awk 'BEGIN{FS=" -> "}/->/{print ;}'`;
            cmdline=`cat /proc/$pid/cmdline`

            local_adr_hex=${ipportinode%%|*}
            remote_adr_hex=${ipportinode#*|}
            remote_adr_hex=${remote_adr_hex%%|*}

            if [ "#${protocol#???}" = "#6" ]; then
                local_adr=$(ip6hex2dec $local_adr_hex)
                remote_adr=$(ip6hex2dec $remote_adr_hex)
            else
        local_adr=$(ip4hex2dec $local_adr_hex)
        remote_adr=$(ip4hex2dec $remote_adr_hex)
            fi 

            echo "$protocol pid:$pid \t$local_adr \t$remote_adr \tinode:$inode \t$exefile $cmdline" 
    done
    done  
done

回答by Jimmy Olsen

With ls you can know the process route.

使用 ls 可以知道流程路线。

Example:

例子:

fuser 25/tcp

The fuser command says that the process is: 2054

熔断器命令说进程是:2054

ls -l /proc/2054/exe

The process path appears

进程路径出现

Extracted from: https://www.sysadmit.com/2018/06/linux-que-proceso-usa-un-puerto.html

摘自:https: //www.sysadmit.com/2018/06/linux-que-proceso-usa-un-puerto.html

Image example

图片示例