2009-11-13 16 views
6

मैं वर्तमान प्रक्रिया के माता-पिता की प्रक्रिया आईडी कैसे प्राप्त कर सकता हूं?
सामान्य रूप से एक प्रक्रिया आईडी दी गई है कि मैं अपनी मूल प्रक्रिया आईडी कैसे प्राप्त कर सकता हूं?
उदा। os.getpid() को माता-पिता के लिए proccess id, और os.getppid() प्राप्त करने के लिए उपयोग किया जा सकता है, मैं दादाजी कैसे प्राप्त करूं,प्रक्रिया की दादाजी आईडी कैसे प्राप्त करें

मेरा लक्ष्य linux (ubuntu) है इसलिए प्लेटफ़ॉर्म विशिष्ट उत्तर ठीक हैं।

+4

os.getpppid()? – paxdiablo

+1

हाँ और बेहतर होगा os.pnid (pid, n) या बस os.getppid (pid) –

उत्तर

7

linux विशिष्ट:

os.popen("ps -p %d -oppid=" % os.getppid()).read().strip() 
+0

स्वाभाविक रूप से परवाह करता है, यह तब तक विंडोज़ पर काम नहीं करता जब तक कि आपके पास साइगविन स्थापित न हो। – ddaa

+0

मुझे लिनक्स के लिए कुछ काम करता है, मेरे लिए कुछ आसान, सरल और सरल :) –

+0

+1 मेरे से एक सरल समाधान के लिए। – paxdiablo

0

मुझे नहीं लगता कि आप सामान्य मामले में यह पोर्टेबल कर सकते हैं।

आपको यह जानकारी प्रक्रिया सूची से प्राप्त करने की आवश्यकता है (उदा। ps कमांड के माध्यम से), जो सिस्टम-विशिष्ट तरीके से प्राप्त की जाती है।

+0

ऐसा नहीं लगता कि वह पोर्टेबिलिटी –

4

मुझे नहीं लगता कि आप एक पोर्टेबल अजगर फैशन में ऐसा कर सकते हैं करते हैं। लेकिन दो संभावनाएं हैं।

  1. जानकारी ps कमांड से उपलब्ध है ताकि आप इसका विश्लेषण कर सकें।
  2. यदि आपके पास proc फ़ाइल सिस्टम के साथ कोई सिस्टम है, तो आप फ़ाइल /proc/<pid>/status फ़ाइल खोल सकते हैं और PPid: वाली लाइन की खोज कर सकते हैं, फिर उस पीआईडी ​​के लिए ऐसा ही करें।

उदाहरण के लिए निम्न स्क्रिप्ट आप अपने पीआईडी, PPID और PPPID, अनुमतियों को तैयार हो जाएगा:

#!/bin/bash 
pid=$$ 
ppid=$(grep PPid: /proc/${pid}/status | awk '{print $2'}) 
pppid=$(grep PPid: /proc/${ppid}/status | awk '{print $2'}) 
echo ${pid} ${ppid} ${pppid} 
ps -f -p "${pid},${ppid},${pppid}" 

पैदा करता है:

3269 3160 3142 
UID  PID PPID C STIME TTY   TIME CMD 
pax  3142 2786 0 18:24 pts/1 00:00:00 bash 
root  3160 3142 0 18:24 pts/1 00:00:00 bash 
root  3269 3160 0 18:34 pts/1 00:00:00 /bin/bash ./getem.sh 
जाहिर

, आप उन फ़ाइलों को खोलने होगा पायथन के साथ।

+0

+1 अच्छा काम करने वाला उदाहरण है, लेकिन पिक्सेलबीट का जवाब आसानी से काम करता है, वहां कोई चेतावनी है? –

+0

नहीं, पिक्सेलबीट ठीक दिखता है और वास्तव में, मैंने इसे हटा दिया है क्योंकि यह मेरी विधि से एक आसान है - मुझे उन विकल्पों के बारे में पता नहीं था, जो * बहुत * शुरुआती यूनिक्स दिनों से आते हैं :-) – paxdiablo

+0

मैंने आपका जवाब संपादित किया (पीएस लाइन)। पीएस आउटपुट फ़िल्टर करने के लिए grep का उपयोग गलत परिणाम दे सकता है (लगता है कि पीपीपीआईडी ​​1 था, उदाहरण के लिए)। -p विकल्प, वैसे, काफी पुराना है। – tzot

0

आप एक POSIX अनुरूप 'ps' कमांड है, जो आपको वांछित स्तंभ निर्दिष्ट कर सकते हैं, इस तरह है: ps -o pid,ppid

फिर आप की कोशिश कर सकते:

import os 
import re 

ps = os.popen("ps -o pid,ppid") 
ps.readline() # discard header 
lines = ps.readlines() 
ps.close 

procs = [ re.split("\s+", line.strip()) for line in lines ] 

parent = {} 
for proc in procs: 
    parent[ int(proc[0]) ] = int(proc[1]) 

अब आप कर सकते हैं है:

parent[ parent[pid] ] 

तुम भी एक प्रक्रिया 'पूर्वजों सूची एक समारोह लिख सकते हैं:

def listp(pid): 
    print(pid) 
    if parent.has_key(pid): 
     listp(parent[pid]) 
+2

line.split() re.split (r "\ s +", line.strip()) के बजाय काम करेगा। डिफ़ॉल्ट विभाजन() \ s + पर विभाजित होता है और अग्रणी और पिछला सफेद स्थान हटा देता है। –

2
from __future__ import with_statement 

def pnid(pid=None, N=1): 
    "Get parent (if N==1), grandparent (if N==2), ... of pid (or self if not given)" 
    if pid is None: 
     pid= "self" 

    while N > 0: 
     filename= "/proc/%s/status" % pid 
     with open(filename, "r") as fp: 
      for line in fp: 
       if line.startswith("PPid:"): 
        _, _, pid= line.rpartition("\t") 
        pid= pid.rstrip() # drop the '\n' at end 
        break 
      else: 
       raise RuntimeError, "can't locate PPid line in %r" % filename 
     N-= 1 

    return int(pid) # let it fail through 


>>> pnid() 
26558 
>>> import os 
>>> os.getppid() 
26558 
>>> pnid(26558) 
26556 
>>> pnid(N=2) 
26556 
>>> pnid(N=3) 
1 
+0

बीटीडब्ल्यू, मैंने लोगों से अक्सर मुझसे पूछा है कि मैं पीईपी -8 का पालन क्यों नहीं करता हूं और इसे निर्दिष्ट करते समय नाम के बाद कभी भी अंतरिक्ष का उपयोग नहीं करता; यह एक पुरानी आदत है जिसे मैंने सी कोड के लिए विकसित किया और इसे रखा; पिछले कुछ सालों से मैं "==" बग (या सिंटैक्स त्रुटि) के बजाय "=" द्वारा काट गया है। – tzot

+0

पीएनआईडी के लिए +1, लेकिन रिकर्सिव नहीं होगा "ps -p% d -oppid ="% pid बहुत छोटा और स्पष्ट होगा –

+0

यह एक एकल प्रक्रिया पायथन लिपि है; मुझे एक शेल स्क्रिप्ट के लिए एक रिकर्सिव 'ps' अधिक उपयुक्त लगता है। मैं पाइथन को जेनेरिक/बिन/sh प्रतिस्थापन के रूप में नहीं मानता। आपकी टिप्पणी में "+1" के लिए धन्यवाद, वैसे भी। – tzot

20

psutil (https://github.com/giampaolo/psutil) का उपयोग करके:

>>> import psutil 
>>> psutil.Process().ppid() 
2335 
>>> psutil.Process().parent() 
<psutil.Process (pid=2335, name='bash', cmdline='bash') at 140052120886608> 
>>> 
+1

यह अधिक विश्वसनीय उत्तर है, psutil एक lifesaver है। – blented

+0

यह 'os.getpid()' के बजाय 'os.getppid()' होना चाहिए। 'Psutil.Process (os.getpid()) के बजाय' os.getppid() 'का उपयोग करें। पीपीआईडी ​​()' (* माता-पिता के * पिड को वापस करने के लिए)। * "प्रक्रिया की दादाजी आईडी प्राप्त करने के लिए" * ओपी पूछता है, 'psutil.Process (os.getppid()) का उपयोग करें। पीपीआईडी ​​() '(नोटिस:' getppid() ',' getpid() 'नहीं)। – jfs

संबंधित मुद्दे