Поиск команды для конкретного PID в Linux из Python - PullRequest
7 голосов
/ 17 сентября 2009

Хотелось бы узнать, можно ли узнать «команду», на которую установлен PID. Когда я говорю «команда», я имею в виду то, что вы видите в последнем столбце, когда запускаете команду «top» в оболочке Linux. Я хотел бы получить эту информацию от Python, когда у меня есть конкретный PID.

Любая помощь будет отличной. Спасибо.

Ответы [ 7 ]

11 голосов
/ 18 сентября 2009

ПОЖАЛУЙСТА, не используйте /proc файловую систему в рабочем коде. Вместо этого используйте четко определенные интерфейсы POSIX, такие как вызовы glibc и стандартные команды оболочки! Сделайте мир Linux более стандартизированным, это действительно необходимо!

То, что вам нужно, хорошо достигается с помощью команды оболочки

ps -p <YOUR PID> -o cmd h

Не нужно разбирать!

Не говоря уже о том, что чтение вывода команды оболочки из python требует не больше усилий, чем чтение из файла в /proc. И это также делает вашу программу более переносимой!

8 голосов
/ 17 сентября 2009

Посмотрите /proc/$PID/cmdline

6 голосов
/ 17 сентября 2009

Прочитайте команду ps и проанализируйте ее вывод.

ps -p [PID] -o cmd 

должен это сделать

5 голосов
/ 18 сентября 2009

Просмотрите /proc/$PID/cmdline, а затем os.readlink () на /proc/$PID/exe.

/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)" после него, если исполняемый файл больше не находится в файловой системе.

Кроме того, программа, представляющая собой текстовый сегмент, не всегда то, что вы хотите. Например, /proc/$PID/exe из этого /usr/sbin/postgrey примера выше - /usr/bin/perl. Это будет иметь место для всех интерпретируемых сценариев (#!).

Я остановился на синтаксическом анализе /proc/$PID/cmdline - взял первый элемент вектора, а затем искал в нем пробелы и взял все перед первым пробелом. Если это был исполняемый файл - я остановился на этом. В противном случае я сделал readlink (2) на /proc/$PID/exe и удалил все строки "(deleted)" на конце. Эта первая часть потерпит неудачу, если в исполняемом имени файла есть пробелы. Вы ничего не можете с этим поделать.

КСТАТИ. Аргумент использовать ps (1) вместо /proc/$PID/cmdline не применим в этом случае, так как вы собираетесь вернуться к /proc/$PID/exe. Вы будете зависеть от файловой системы /proc, поэтому вы можете также прочитать ее с помощью read (2) вместо pipe (2), fork (2), execve (2), readdir (3) ..., write ( 2) читать (2). Хотя ps и /proc/$PID/cmdline могут быть одинаковыми с точки зрения строк кода на Python, за кулисами с ps происходит гораздо больше.

4 голосов
/ 15 августа 2012

Интересный пакет Python: psutil .

Например, чтобы получить команду для определенного 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
0 голосов
/ 05 августа 2015

Это сработало для меня:

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
0 голосов
/ 17 сентября 2009

Файловая система proc экспортирует эту (и другую) информацию. Посмотрите на символическую ссылку / proc / PID / cmd.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...