पाइप के साथ `सबप्रोसेस` कमांड का उपयोग कैसे करें


246

मैं के subprocess.check_output()साथ उपयोग करना चाहते हैं ps -A | grep 'process_name'। मैंने विभिन्न समाधानों की कोशिश की लेकिन अभी तक कुछ भी काम नहीं आया। क्या कोई मुझे गाइड कर सकता है कि मैं इसे कैसे करूं?



4
वहाँ है psutilकि एक पोर्टेबल तरीके से प्रक्रिया की जानकारी प्राप्त करने की अनुमति देता है।
JFS

जवाबों:


439

subprocessमॉड्यूल के साथ एक पाइप का उपयोग करने के लिए , आपको पास करना होगा shell=True

हालांकि, यह वास्तव में विभिन्न कारणों से उचित नहीं है, जिनमें से कम से कम सुरक्षा नहीं है। इसके बजाय, बनाने psऔर grepप्रक्रियाओं को अलग से एक से उत्पादन दूसरे में, है, और पाइप इसलिए की तरह:

ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
ps.wait()

हालाँकि, आपके विशेष मामले में, सरल समाधान कॉल करना है subprocess.check_output(('ps', '-A'))और फिर str.findआउटपुट पर है।


81
उपयोग करने से बचने के लिए आउटपुट / इनपुट को अलग करने के लिए +1shell=True
निकोलस

5
मत भूलो, त्रुटि का subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1मतलब सिर्फ इतना है कि कुछ भी नहीं मिला, इसलिए यह सामान्य व्यवहार है।
सर्ज

2
ps.wait()जब हमारे पास पहले से ही आउटपुट है तो हमें इसकी आवश्यकता क्यों है । ps.wait.__doc__बच्चे के समाप्त होने की प्रतीक्षा करता है, लेकिन बच्चे की सामग्री पहले से ही outputचर में रखी हुई लगती है
पापोच गुइंसलीज़िन्हो

3
@MakisH आप देख रहे हैं string.find, जो str.find(यानी, वस्तुओं findपर विधि str) के पक्ष में चित्रित किया गया है ।
तैमूर

4
नोट: यदि grepसमय से पहले मृत्यु हो जाती है; psयदि यह अपने OS पाइप बफर को भरने के लिए पर्याप्त उत्पादन का उत्पादन करता है, तो अनिश्चित काल तक लटका रह सकता है (क्योंकि आपको ps.stdout.close()माता-पिता में नहीं बुलाया गया है)। शुरुआती आदेश को स्वैप करें, इससे बचने के लिए
jfs

54

या आप हमेशा उपप्रोसेस ऑब्जेक्ट पर संचार विधि का उपयोग कर सकते हैं।

cmd = "ps -A|grep 'process_name'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)

संचार विधि मानक आउटपुट और मानक त्रुटि का एक टपल देता है।


3
मुझे लगता है कि का उपयोग communicateकरना बेहतर है waitइस तरह की चेतावनी है: "stdout = PIPE और / या stderr = PIPE का उपयोग करते समय यह गतिरोध करेगा और बच्चे की प्रक्रिया एक पाइप में पर्याप्त आउटपुट उत्पन्न करती है, जिससे यह अधिक डेटा स्वीकार करने के लिए OS पाइप बफर के इंतजार में ब्लॉक का उपयोग करता है। उससे बचो। "
पाओलो

2
उपरोक्त पाओलो की टिप्पणी को स्पष्ट करने के लिए, चेतावनी प्रतीक्षा के लिए है, संवाद के लिए नहीं - अर्थात यह कारण है कि वह कहता है कि संचार बेहतर है।
EnemyBagJones

23

सबप्रोसेस का उपयोग करके पाइपलाइन स्थापित करने के बारे में दस्तावेज देखें: http://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline

मैंने निम्नलिखित कोड उदाहरण का परीक्षण नहीं किया है, लेकिन यह लगभग वही होना चाहिए जो आप चाहते हैं:

query = "process_name"
ps_process = Popen(["ps", "-A"], stdout=PIPE)
grep_process = Popen(["grep", query], stdin=ps_process.stdout, stdout=PIPE)
ps_process.stdout.close()  # Allow ps_process to receive a SIGPIPE if grep_process exits.
output = grep_process.communicate()[0]

2
यह विफल होने पर जाँच करने पर, बिना किसी छेड़छाड़ के काम करने वाली चीज़ के लिए तैमोन द्वारा नीचे दिए गए उत्तर को देखें
एल्विन


6

JKALAVIS समाधान अच्छा है, हालांकि मैं शेल = ट्रायल के बजाय श्लेक्स का उपयोग करने के लिए एक सुधार जोड़ूंगा। नीचे क्वेरी बाहर grepping बार

#!/bin/python
import subprocess
import shlex

cmd = "dig @8.8.4.4 +notcp www.google.com|grep 'Query'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)

1
शेल पर शेल क्यों?
AFP_555

2
श्लेक्स यहाँ कहाँ उपयोग किया जाता है?
3lokh

4

इसके अलावा, इसके 'pgrep'बजाय कमांड का उपयोग करने का प्रयास करें'ps -A | grep 'process_name'


2
अगर आप प्रक्रिया आईडी प्राप्त करना चाहते हैं, तो जाहिर है
शू


-1

पायथन 3.5 के बाद आप भी उपयोग कर सकते हैं:

    import subprocess

    f = open('test.txt', 'w')
    process = subprocess.run(['ls', '-la'], stdout=subprocess.PIPE, universal_newlines=True)
    f.write(process.stdout)
    f.close()

कमांड का निष्पादन ब्लॉक हो रहा है और आउटपुट प्रोसेस में होगा ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.