2013-02-02 44 views
2

/proc/net/tcp爲套接字(例如,0.0.0.0:5432和9289)提供本地地址,端口和inode編號。在Python 3中查找給定套接字和inode的進程ID

鑑於上述信息,我想找到特定進程的PID。

可以打開/ proc中的每個編號文件夾,然後使用shell命令(如「$ sudo ls -l/proc/*/fd/2>/dev/null |」)檢查符號鏈接是否匹配套接字/ inode編號。 grep套接字「。但是,這似乎在計算上比所需的更昂貴,因爲任何給定系統上的進程的5%都有開放的TCP套接字。

找到打開給定套接字的PID的最有效方法是什麼?我寧願使用標準庫,而我目前正在使用Python 3.2.3進行開發。

編輯:從問題中刪除了代碼示例,因爲它們現在包含在下面的答案中。

+0

關於標準庫,我想盡量避免使用subprocess.call或os.exec,並盡一切內部的Python工作本身。 – 5ba8cabe450348c7fbe2

+1

讀取procfs,使用lsof或使用netstat似乎沒有多少選擇。我猜他們都是一樣的(讀取procfs)。不幸的是沒有其他的事情要做。很多類似的SO問題都有相同的答案:1. read/proc/net/tcp 2. read/proc//fd /。 – emil

+0

我使用os.readlink和os.listdir添加了一些工作代碼 - 沒有子進程調用。我看到的問題是,我所做的os.readlink調用遠遠超過必要的 - 大約需要600次調用才能找到大約四個打開的套接字的PID。 – 5ba8cabe450348c7fbe2

回答

3

下面的代碼完成了最初的目標:

def find_pid(inode): 

    # get a list of all files and directories in /proc 
    procFiles = os.listdir("/proc/") 

    # remove the pid of the current python process 
    procFiles.remove(str(os.getpid())) 

    # set up a list object to store valid pids 
    pids = [] 

    for f in procFiles: 
     try: 
      # convert the filename to an integer and back, saving the result to a list 
      integer = int(f) 
      pids.append(str(integer)) 
     except ValueError: 
      # if the filename doesn't convert to an integer, it's not a pid, and we don't care about it 
      pass 

    for pid in pids: 
     # check the fd directory for socket information 
     fds = os.listdir("/proc/%s/fd/" % pid) 
     for fd in fds: 
      # save the pid for sockets matching our inode 
      if ('socket:[%d]' % inode) == os.readlink("/proc/%s/fd/%s" % (pid, fd)): 
       return pid 
+1

也許應該這樣做:'if('socket:[%d]'%inode)== os.readlink(「/ proc /%s/fd /%s」%(pid,fd)):''不匹配inode只是一個子字符串的inode。但除此之外,我認爲它看起來不錯。不知道是否有更有效的方法。 – emil

+0

感謝您的建議 - 我編輯了上面的代碼。我想不出一種更快的方法,所以我會繼續,並將其標記爲已解決。謝謝! – 5ba8cabe450348c7fbe2

2

我不知道如何在Python做到這一點,但你可以使用lsof(1)

lsof -i | awk -v sock=158384387 '$6 == sock{print $2}' 

158384387是套接字索引節點。然後使用subprocess.Popen從python調用它。

如果你想看到其他的套接字,你將不得不使用sudo(8)。

相關問題