के लिए अंगूठे के कुछ नियम subprocess
।
- कभी उपयोग न करें
shell=True
। यह अनावश्यक रूप से आपके प्रोग्राम को कॉल करने के लिए एक अतिरिक्त शेल प्रक्रिया को आमंत्रित करता है।
- कॉल करने की प्रक्रिया के दौरान, तर्कों को सूचियों के रूप में पास किया जाता है।
sys.argv
अजगर में एक सूची है, और इसलिए argv
सी में है। तो आप एक स्ट्रिंग नहीं उप-वर्गों को कॉल करने के लिए एक सूची पास करते हैं Popen
।
- रीडायरेक्ट न करें
stderr
एक करने के लिए PIPE
जब आप इसे पढ़ नहीं रहे हैं।
stdin
जब आप इसे नहीं लिख रहे हैं तो पुनर्निर्देशित न करें ।
उदाहरण:
import subprocess, time, os, sys
cmd = ["rsync.exe", "-vaz", "-P", "source/" ,"dest/"]
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in iter(p.stdout.readline, b''):
print(">>> " + line.rstrip())
उस ने कहा, यह संभावित है कि rsync अपने आउटपुट को बफ़र करता है जब यह पता लगाता है कि यह टर्मिनल के बजाय पाइप से जुड़ा है। यह डिफ़ॉल्ट व्यवहार है - जब पाइप से जुड़ा होता है, तो प्रोग्राम को वास्तविक समय के परिणामों के लिए स्पष्ट रूप से फ्लशआउट करना चाहिए, अन्यथा मानक सी लाइब्रेरी बफर हो जाएगी।
इसके लिए परीक्षण करने के लिए, इसके बजाय इसे चलाने का प्रयास करें:
cmd = [sys.executable, 'test_out.py']
और test_out.py
सामग्री के साथ एक फ़ाइल बनाएँ :
import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")
यह कहते हुए कि उपप्रकार आपको "हैलो" देना चाहिए और "दुनिया" देने से पहले 10 सेकंड प्रतीक्षा करें। यदि ऐसा ऊपर के अजगर कोड के साथ होता है और इसके साथ नहीं होता है rsync
, तो इसका मतलब rsync
है कि इसका आउटपुट बफ़र कर रहा है, इसलिए आप भाग्य से बाहर हैं।
एक समाधान के लिए प्रत्यक्ष कनेक्ट करने के लिए होगा pty
, जैसे कुछ का उपयोग कर pexpect
।