子流程.在windows和linux中使用Popen和shlex.split格式



我正在编写一个包装器,通过Python(2.7.2)自动化一些android ADB shell命令。由于在某些情况下,我需要异步运行命令,所以我使用的是子流程。Popen方法来发出shell命令。

我遇到了Popen方法的[command, 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()获得了相同的结果。

当我关闭shell=True 时,它们的功能似乎相同

根据文件:

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

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

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

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

相关内容

  • 没有找到相关文章

最新更新