2012-02-17 13 views
5

मैं पाइथन (2.7.2) के माध्यम से कुछ एंड्रॉइड एडीबी खोल कमांड को स्वचालित करने के लिए एक रैपर लिख रहा हूं। चूंकि, कुछ मामलों में, मुझे अतुल्यकालिक आदेश चलाने की आवश्यकता है, मैं subprocess का उपयोग कर रहा हूं। खोल आदेश जारी करने के लिए विधि विधि।subprocess.Popen और shlex.split स्वरूपण विंडोज़ और लिनक्स में

# sample command with parameters 
cmd = 'adb -s <serialnumber> shell ls /system' 

# Windows: 
s = subprocess.Popen(cmd.split(), shell=False) # command is split into args by spaces 

# Linux: 
s = subprocess.Popen([cmd], shell=False) # command is a list of length 1 containing whole command as single string 

मैं shlex .split उपयोग करने की कोशिश की है:

मैं Popen विधि है, जहां आदेश/आर्ग विभाजन वहाँ की आवश्यकता होती है [command, args] पैरामीटर के स्वरूपण के साथ किसी समस्या का सामना किया है विंडोज और लिनक्स के बीच अलग है(), पॉज़िक्स ध्वज के साथ और साथ:

# Windows 
posix = False 
print shlex.split(cmd, posix = posix), posix 
# Linux 
posix = True 
print shlex.split(cmd, posix = posix), posix 

दोनों मामले एक ही विभाजन को वापस करते हैं।

वहाँ subprocess में एक विधि है या shlex कि ओएस-विशिष्ट प्रारूपों सही ढंग से संभालती है?

यह मेरे वर्तमान समाधान है:

import os 
import tempfile 
import subprocess 
import shlex 

# determine OS type 
posix = False 
if os.name == 'posix': 
    posix = True 

cmd = 'adb -s <serialnumber> shell ls /system' 
if posix: # posix case, single command string including arguments 
    args = [cmd] 
else: # windows case, split arguments by spaces 
    args = shlex.split(cmd) 

# capture output to a temp file 
o = tempfile.TemporaryFile() 
s = subprocess.Popen(args, shell=False, stdout=o, stderr=o) 
s.communicate() 
o.seek(0) 
o.read() 
o.close() 

मुझे नहीं लगता कि shlex.split() यहाँ कुछ भी कर रही है, और cmd.split() समान परिणाम प्राप्त होता है।

+0

आपने प्रश्न में एक टाइपो बनाया है। शेलेक्स बनाम शेक्स। – jgritty

+0

@jgritty धन्यवाद। सही किया। –

+1

आप 'shell = True' का उपयोग क्यों करते हैं? – jfs

उत्तर

5

वे जब मैं डॉक्स के अनुसार shell=True

बंद कर देते हैं हूबहू ढंग से काम करने लगते हैं: शेल के साथ

यूनिक्स पर, = सच: यदि आर्ग एक स्ट्रिंग है , यह खोल के माध्यम से निष्पादित करने के लिए कमांड स्ट्रिंग निर्दिष्ट करता है। इसका मतलब है कि स्ट्रिंग को स्वरूपित किया जाना चाहिए जैसा कि शेल प्रॉम्प्ट पर टाइप किया जाएगा। इसमें उदाहरण के लिए, उद्धरण या बैकस्लैश को रिक्त स्थान के साथ फ़ाइल नाम से बचाना शामिल है। अगर तर्क एक अनुक्रम है, तो पहला आइटम कमांड स्ट्रिंग निर्दिष्ट करता है, और कोई भी अतिरिक्त आइटम को खोल के लिए अतिरिक्त तर्क के रूप में माना जाएगा।

popen ([ '/ bin/sh', '-c', args [0], args [1], ...])

: यह कहने के लिए, popen के बराबर करता है

http://docs.python.org/library/subprocess.html

+1

शैल द्वारा निष्पादित आदेश के बजाए तर्क लेना, समस्या बताता है (और समाधान) पूरी तरह से। 'खोल = गलत' 'args = cmd.split()' और 'subprocess.Popen (args, shell = झूठा) 'लिनक्स और विंडोज दोनों पर समान रूप से व्यवहार करते हैं। –

4

shell=True तर्क यह बताता है कि आपके शेल द्वारा कमांड लाइन का मूल्यांकन किया गया है, जो विंडोज़ पर Cmd.exe होगा; लिनक्स पर, यह /bin/bash होगा, लेकिन कुछ अन्य संबंधित खोल भी हो सकता है (zsh, tcsh, आदि)। व्यवहार में अंतर अलग-अलग आदेशों को व्याख्या करने वाले गोले के कारण होने की संभावना है।

यदि आप इससे बच सकते हैं तो मैं shell=True का उपयोग करके दृढ़ता से अनुशंसा करता हूं। बस कुछ इस तरह:

cmd = 'adb -s <serialnumber> shell ls /system' 
s = subprocess.Popen(cmd.split()) # shell=False by default 
संबंधित मुद्दे