Подтвердить что ты не робот

Проверьте, запущен ли процесс с использованием Python в Linux

Я пытаюсь найти, работает ли процесс на основе идентификатора процесса. Код выглядит следующим образом, основываясь на одном из сообщений на форуме. Я не могу рассматривать имя процесса, поскольку существует несколько процессов, работающих под тем же именем.

def findProcess( processId ):
    ps= subprocess.Popen("ps -ef | grep "+processId, shell=True, stdout=subprocess.PIPE)
    output = ps.stdout.read()
    ps.stdout.close()
    ps.wait()
    return output
def isProcessRunning( processId):
    output = findProcess( processId )
    if re.search(processId, output) is None:
        return true
    else:
        return False

Выход:

1111 72312 72311   0   0:00.00 ttys000    0:00.00 /bin/sh -c ps -ef | grep 71676
1111 72314 72312   0   0:00.00 ttys000    0:00.00 grep 71676

Он всегда возвращает true, так как он может найти идентификатор процесса в выходной строке.

Любые предложения? Спасибо за любую помощь.

4b9b3361

Ответ 1

Try:

os.kill(pid, 0)

Должен преуспеть (и ничего не делать), если процесс существует, или выбросить исключение (которое вы можете поймать), если процесс не существует.

Ответ 2

Самый простой ответ на мой взгляд (albiet, возможно, не идеальный), - это изменить ваш

ps -ef | grep <pid>

To:

ps -ef | grep <pid> | grep -v grep

Это будет игнорировать список процессов для поиска grep, содержащего PID процесса, который вы пытаетесь найти.

Кажется, user9876 ответ гораздо более "pythonic".

Ответ 4

Это немного kludge, но на * nix вы можете использовать os.getpgid(pid) или os.kill(pid, sig), чтобы проверить наличие идентификатора процесса.

import os

def is_process_running(process_id):
    try:
        os.kill(process_id, 0)
        return True
    except OSError:
        return False

EDIT: Обратите внимание, что os.kill работает в Windows (как и на Python 2.7), а os.getpgid - нет. Но версия Windows вызывает TerminateProcess(), которая "безоговорочно заставит процесс выйти", поэтому я предсказываю, что он не будет безопасным вернуть требуемую информацию, не убивая процесс, если он существует.

Если вы используете Windows, сообщите нам об этом, потому что ни одно из этих решений не приемлемо в этом сценарии.

Ответ 5

Я знаю, что это старо, но я использовал это и, похоже, работает; вы можете быстро адаптироваться к преобразованию из имени процесса в идентификатор процесса:

 try:
    if len( os.popen( "ps -aef | grep -i 'myprocess' | grep -v 'grep' | awk '{ print $3 }'" ).read().strip().split( '\n' ) ) > 1:
        raise SystemExit(0)
 except Exception, e:
        raise e

Ответ 6

Если вы не против использования внешнего модуля, я бы предложил psutil. Это кросс-платформенный и более простой в использовании, чем нерестовая подоболочка только для поиска текущего процесса.

Ответ 7

Если этот процесс принадлежит одному и тому же пользователю в процессе проверки, вы можете просто попробовать kill его. Если вы используете сигнал 0, kill не отправит ничего, но все же позволит вам узнать, доступен ли процесс.

От kill(2):

Если sig равно 0, тогда никакой сигнал не отправляется, но проверка ошибок по-прежнему выполнено; это можно использовать для проверки наличия идентификатора процесса или идентификатор группы процессов.

Это должно соответствующим образом распространяться на методы python.

Ответ 8

В Windows другой вариант - использовать tasklist.exe:

Синтаксис: tasklist.exe/NH/FI "PID eq processID"

def IsProcessRunning( processId ):
    ps= subprocess.Popen(r'tasklist.exe /NH /FI "PID eq %d"' % (processId), shell=True, stdout=subprocess.PIPE)
    output = ps.stdout.read()
    ps.stdout.close()
    ps.wait()
    if processId in output:
       return True
    return False

Ответ 9

В Windows вы можете использовать WMI.

from win32com.client import GetObject
GetObject('winmgmts:').ExecQuery("Select * from Win32_Process where ProcessId = " + str(pid)).count

Вы также можете использовать другие фильтры. Например, я, скорее всего, просто хочу сказать, работает ли процесс по имени и предпринимает действия. Например, если DbgView не запущен, запустите его.

if not GetObject('winmgmts:').ExecQuery("Select * from Win32_Process where Name = 'dbgview.exe'").count:
    subprocess.Popen(r"C:\U\dbgview.exe", shell=False)

Вы также можете перебирать и делать другие интересные вещи. Полный список полей здесь.

Ответ 10

Недавно мне пришлось перечислить запущенные процессы и сделать это:

def check_process(process):
  import re
  import subprocess

  returnprocess = False
  s = subprocess.Popen(["ps", "ax"],stdout=subprocess.PIPE)
  for x in s.stdout:
      if re.search(process, x):
          returnprocess = True

  if returnprocess == False:        
      print 'no process executing'
  if returnprocess == True:
      print 'process executing'

Ответ 11

Вы должны найти его дважды..

Вот так:

ps -ef | grep 71676 | sed 's/71676//' | grep 71676

Если это возвращает True, тогда это действительно работает!!