के लिए अंगूठे के कुछ नियम 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।