Nis*_*n.H 6 python subprocess shlex
我正在编写一个包装器来通过Python(2.7.2)自动化一些Android ADB shell命令.因为,在某些情况下,我需要异步运行命令,我使用子进程.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
Run Code Online (Sandbox Code Playgroud)
我尝试使用shlex .split(),带有posix标志:
# Windows
posix = False
print shlex.split(cmd, posix = posix), posix
# Linux
posix = True
print shlex.split(cmd, posix = posix), posix
Run Code Online (Sandbox Code Playgroud)
两种情况都返回相同的分裂.
是否有一种方法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()
Run Code Online (Sandbox Code Playgroud)
我认为shlex.split()这里没有做任何事情,并cmd.split()取得了相同的结果.
该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
Run Code Online (Sandbox Code Playgroud)
当我关闭时,它们似乎功能完全相同 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