簡體   English   中英

從Python查找Linux中特定PID的命令

[英]Finding the command for a specific PID in Linux from Python

我想知道是否有可能找出PID設置為的“命令”。 當我說命令時,我的意思是您在Linux shell中運行命令“ top”時在最后一欄中看到的內容。 當我具有特定的PID時,我想以某種方式從Python獲取此信息。

任何幫助都會很棒。 謝謝。

請不要在生產代碼中使用/proc文件系統。 而是使用定義明確的POSIX接口,例如glibc調用和標准的shell命令! 使Linux世界更加標准化,這確實需要!

通過調用shell命令可以很好地實現您所需要的

ps -p <YOUR PID> -o cmd h

無需解析!

更不用說從python讀取shell命令輸出要比從/proc的文件讀取更多的工作。 而且,這也使您的程序更加可移植!

/proc/$PID/cmdline查找

閱讀ps命令並解析其輸出。

ps -p [PID] -o cmd 

應該做

/proc/$PID/cmdline查找,然后在/proc/$PID/exe查找os.readlink()。

/proc/$PID/cmdline不一定正確,因為程序可以更改其自變量矢量或不包含完整路徑。 我當前的流程列表中的三個示例是:

  • avahi-daemon: chroot helper
  • qmgr -l -t fifo -u
  • /usr/sbin/postgrey --pidfile=/var/run/postgrey.pid --daemonize --inet=127.0.0.1:60000 --delay=55

第一個很明顯-它不是有效的路徑或程序名稱。 第二個只是沒有路徑名的可執行文件。 第三個看起來不錯,但是整個命令行實際上位於argv[0] ,用空格分隔參數。 通常,您應該使用NUL分隔的參數。

所有這一切都表明/proc/$PID/cmdline (或ps(1)輸出)不可靠。

但是/proc/$PID/exe也沒有。 通常,它是指向可執行文件的符號鏈接,該可執行文件是進程的主要文本段。 但是,如果可執行文件不再位於文件系統中,則有時它后面會帶有“ (deleted) ”。

另外,作為文本段的程序也不總是您想要的。 例如,上面的/usr/sbin/postgrey示例中的/proc/$PID/exe/usr/bin/perl 所有已解釋的腳本(#!)都是這種情況。

我決定解析/proc/$PID/cmdline獲取向量的第一個元素,然后在其中尋找空格,並在第一個空格之前獲取所有空格。 如果那是一個可執行文件-我就停在那里。 否則,我在/proc/$PID/exe上執行了readlink(2),最后刪除了所有“ (deleted) ”字符串。 如果可執行文件名中實際包含空格,則第一部分將失敗。 您對此無能為力。

順便說一句。 在這種情況下,使用ps(1)代替/proc/$PID/cmdline不適用,因為您將退回到/proc/$PID/exe 您將依賴於/proc文件系統,因此也可以使用read(2)而不是pipe(2),fork(2),execve(2),readdir(3)...,write(2)來讀取它。 ),請閱讀(2)。 從python代碼行的角度來看,雖然ps和/proc/$PID/cmdline可能是相同的,但ps的幕后工作還很多。

psutil是一個有趣的Python包。

例如,要獲取特定PID的命令:

import psutil
pid = 1234 # The pid whose info you're looking for
p = psutil.Process(pid)
print p.cmdline

最后一行將顯示類似['/usr/bin/python', 'main.py']

獲取此信息的更可靠的方法,請注意,如果pid表示某個進程不再運行:

import psutil
pid = 1234 # The pid whose info you're looking for
if pid in psutil.get_pid_list():
    p = psutil.Process(pid)
    print p.cmdline

proc文件系統導出此(和其他)信息。 查看/ proc / PID / cmd符號鏈接。

這為我工作:

def filter_non_printable(str):
    ret=""
    for c in str:
        if ord(c) > 31 or ord(c) == 9:
            ret += c
        else:
            ret += " "
    return ret


#
# Get /proc/<cpu>/cmdline information
#
def pid_name(pid):
    try:
        with open(os.path.join('/proc/', pid, 'cmdline'), 'r') as pidfile:
            return filter_non_printable(pidfile.readline())

    except Exception:
        pass
        return

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM