2012-02-17 15 views
5

私はPython(2.7.2)でいくつかのandroid ADBシェルコマンドを自動化するためのラッパーを作成しています。 場合によっては、コマンドを非同期で実行する必要があるため、subprocess.Popenメソッドを使用してシェルコマンドを発行しています。私はshlex .splitを使用してみましたがsubprocess.Popenとshlex.splitのフォーマットはWindowsとLinuxで

# 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 

私は、コマンド/引数の分割が必要とPopen方法、の[command, args]パラメータのフォーマットに問題に遭遇してきたが、WindowsとLinuxの間で異なっていますposixフラグの有無にかかわらず、

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

どちらの場合も同じ分割が返されます。

subprocessまたはshlexには、OS固有のフォーマットを正しく処理するメソッドがありますか?

これは私の現在のソリューションです:

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

あなたは質問に誤字を入れました。 shlexとshelx – jgritty

+0

@jgrittyありがとうございます。修正されました。 –

+1

なぜ 'shell = True'を使うのですか? – jfs

答えて

5

彼らは私がドキュメントを1としてshell=True

をオフにしたときに同じように機能するように見える:

Unixでは

、shell = Trueの場合:argsが文字列の場合シェルから実行するコマンド文字列を と指定します。つまり、 文字列は、 シェルプロンプトで入力したときとまったく同じにフォーマットする必要があります。これには、たとえば、引用符またはバックスラッシュ にスペースでエスケープするファイル名が含まれます。 argsがシーケンスである場合、最初の項目の はコマンド文字列を指定し、追加の項目はシェル自体に対する追加の引数として扱われます( )。

popenの([ '/ binに/ SH'、 '-c'、引数[0]、引数[1]、...])

:それは にあるpopenのは相当を行い、言います

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

+1

シェルは、実行されるコマンドではなく引数を取って、問題を説明しますソリューション)を完全に。 'shell = False'では' args = cmd.split() 'と' subprocess.Popen(args、shell = False) 'はlinuxとwindowsの両方で同じように動作します。 –

4

shell=True引数は、シェルによって評価されるコマンドラインを持つように指示します.WindowsではCmd.exeとなります。 Linuxでは、おそらく/bin/bashになりますが、他の関連するシェル(zsh、tcshなど)でもかまいません。振る舞いの違いは、シェルがコマンドを異なる方法で解釈することによって引き起こされている可能性があります。

は、shell=Trueを避けることを強くお勧めします。を使用しないことを強くお勧めします。このようなだけで何か:

cmd = 'adb -s <serialnumber> shell ls /system' 
s = subprocess.Popen(cmd.split()) # shell=False by default 
関連する問題