windows和linux中的subprocess.Popen和shlex.split格式

时间:2012-02-17 02:30:51

标签: python subprocess shlex

我正在编写一个包装器来通过Python(2.7.2)自动化一些Android ADB shell命令。 因为,在某些情况下,我需要异步运行命令,我使用subprocess。Popen方法发出shell命令。

我遇到了[command, args]方法的Popen参数格式的问题,其中需要命令/ args拆分在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

我尝试过使用shlex。split(),带有和没有posix标志:

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

两种情况都会返回相同的分割。

subprocessshlex中是否有正确处理特定于操作系统的格式 的方法?

这是我目前的解决方案:

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()取得了相同的结果。

2 个答案:

答案 0 :(得分:5)

当我关闭shell=True

时,它们似乎功能相同

根据文档:

  

在Unix上,shell = True:如果args是一个字符串,则指定   命令字符串通过shell执行。这意味着   string的格式必须与在键入时的格式完全相同   shell提示。这包括,例如,引用或反斜杠   转义带有空格的文件名。如果args是一个序列,那么   第一项指定命令字符串,任何其他项目将   被视为shell本身的附加参数。那就是   比方说,Popen相当于:

     

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

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

答案 1 :(得分:4)

shell=True参数告诉它让你的shell评估命令行,在Windows上它将是Cmd.exe;在Linux上,它可能是/bin/bash,但也可能是其他一些相关的shell(zsh,tcsh等)。行为的差异很可能是由于shell以不同的方式解释命令。

如果您可以避免使用shell=True,我强烈建议。就像这样:

cmd = 'adb -s <serialnumber> shell ls /system'
s = subprocess.Popen(cmd.split())  # shell=False by default