python笔记65 - Python3 subprocess执行命令行获取返回结果

前言

subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。
Popen 是 subprocess的核心,子进程的创建和管理都靠它处理。

subprocess.Popen

subprocess模块定义了一个类:Popen

class Popen(object):
""" Execute a child program in a new process.

For a complete description of the arguments see the Python documentation.

Arguments:
args: A string, or a sequence of program arguments.

bufsize: supplied as the buffering argument to the open() function when
creating the stdin/stdout/stderr pipe file objects

executable: A replacement program to execute.

stdin, stdout and stderr: These specify the executed programs' standard
input, standard output and standard error file handles, respectively.

preexec_fn: (POSIX only) An object to be called in the child process
just before the child is executed.

close_fds: Controls closing or inheriting of file descriptors.

shell: If true, the command will be executed through the shell.

cwd: Sets the current directory before the child is executed.

env: Defines the environment variables for the new process.

universal_newlines: If true, use universal line endings for file
objects stdin, stdout and stderr.

startupinfo and creationflags (Windows only)

restore_signals (POSIX only)

start_new_session (POSIX only)

pass_fds (POSIX only)

encoding and errors: Text mode encoding and error handling to use for
file objects stdin, stdout and stderr.

Attributes:
stdin, stdout, stderr, pid, returncode
"""
_child_created = False # Set here since __del__ checks it

def __init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding=None, errors=None):
"""Create new Popen instance."""

常用参数:

  • args:

    shell命令,可以是字符串或者序列类型(如:

    str, list,元组)

  • bufsize:

    缓冲区大小。

    当创建标准流的管道对象时使用,默认-1。

    0:

    不使用缓冲区
     1:

    表示行缓冲,仅当universal_newlines=True时可用,也就是文本模式
     正数:

    表示缓冲区大小
     负数:

    表示使用系统默认的缓冲区大小。

  • stdin, stdout, stderr:

    分别表示程序的标准输入、输出、错误句柄

  • preexec_fn:

    只在 Unix 平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用

  • shell:

    如果该参数为 True,将通过操作系统的 shell 执行指定的命令。

  • cwd:

    用于设置子进程的当前目录。

  • env:

    用于指定子进程的环境变量。

    如果 env = None,子进程的环境变量将从父进程中继承。

  • encoding:

    设置编码类型

使用示例

一个简单示例,命令行执行pip

import subprocess
p = subprocess.Popen('pip -V',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)

# 输出stdout
print(p.communicate()[0])

得到结果是byte类型的

b'pip 21.1.2 from e:\\python36\\lib\\site-packages\\pip (python 3.6)\r\r\n'

于是可以添加encoding参数utf-8

import subprocess
p = subprocess.Popen('pip -V',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding='utf-8'
)

# 输出stdout
print(p.communicate()[0])

此时输出

pip 21.1.2 from e:\python36\lib\site-packages\pip (python 3.6)

如果输出有中文,会出现解码异常
输入java,正常情况是可以输出中文的

import subprocess
p = subprocess.Popen('java',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding='utf-8'
)

# 输出stdout
print(p.communicate()[0])

但是运行结果就会解码异常

Traceback (most recent call last):
File "D:/tests.py", line 44, in <module>
print(p.communicate()[0])
File "E:\python36\lib\subprocess.py", line 830, in communicate
stdout = self.stdout.read()
File "E:\python36\lib\codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd3 in position 0: invalid continuation byte

原因是windows系统编码是gb2312

windows解码

知道windows系统的编码后,设置对应的编码,就可以正常解码了

import subprocess
p = subprocess.Popen('java',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding='gb2312'
)

# 输出stdout
print(p.communicate()[0])

得到

用法: java [-options] class [args...]
(执行类)
或 java [-options] -jar jarfile [args...]
(执行 jar 文件)
其中选项包括:
-d32 使用 32 位数据模型 (如果可用)
-d64 使用 64 位数据模型 (如果可用)
-server 选择 "server" VM
默认 VM 是 server.

也可以在拿到输出结果后decode解码

import subprocess
p = subprocess.Popen('java',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
# 输出stdout
result = p.communicate()[0]
print(result.decode('gb2312'))

执行python代码,得到stdout内容

接下来写一小段python代码,看执行结果

# xx.py
print("hello world! 这段包含了中文")

使用subprocess.Popen执行,需设置encoding=’utf-8’

import subprocess
p = subprocess.Popen(['python', 'xx.py'],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding='utf-8'
)

# 输出stdout
print(p.communicate()[0])

运行结果

hello world! 这段包含了中文

如果python代码有语法异常

# xx.py
print("hello world! 这段包含了中文"x)

此时是可以输出异常内容的

File "xx.py", line 1
print("hello world! 这段包含了中文"x)
^
SyntaxError: invalid syntax

Popen 对象方法

Popen 对象方法用到的几个方法

  • poll(): 检查进程是否终止,如果终止返回 returncode,否则返回 None。

  • wait(timeout): 等待子进程终止。

  • communicate(input,timeout): 和子进程交互,发送和读取数据。

  • send_signal(singnal): 发送信号到子进程 。

  • terminate(): 停止子进程,也就是发送SIGTERM信号到子进程。

  • kill(): 杀死子进程。

    发送 SIGKILL 信号到子进程。

其它方法参考菜鸟教程https://www.runoob.com/w3cnote/python3-subprocess.html

2021年第 9 期《python接口web自动化+测试开发》课程,10月17号开学!

加量不加价(新增postman, 赠送selenium和python基础2个课

本期上课时间:10月17号-1月9号,每周六、周日晚上20:30-22:30

(0)

相关推荐

  • Shell 输入/输出重定向

    大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端.一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端.同样,一个命令通常将其输出写入到标准输出,默认情 ...

  • Appium 并发测试之 python 启动 appium 服务

    来自 APP Android 端自动化测试初学者的笔记,写的不对的地方大家多多指教哦 python 启动 appium 服务,需要使用 subprocess 模块,该模块可以创建新的进程,并且连接到进 ...

  • Shell脚本控制docker容器启动顺序

    Shell脚本控制docker容器启动顺序

  • 四种执行python系统命令的方法

    Python中执行系统命令常见的几种方法有 注意:以下实例代码在Python3.5下运行通过. 一.os.system方法 os.system(cmd) 在子终端运行系统命令,可以获取命令执行后的返回 ...

  • Unix如何工作:您不敢问的一切

    文件和进程的故事. 成为更好的软件工程师 Unix很美. 请允许我为您画一些快乐的小树. 我不会解释很多命令,这很无聊,网络上已经有上百万的教程可以做到这一点. 我将让您能够对系统进行推理. 您想做的 ...

  • Python 利用argparse模块实现脚本命令行参数解析

    利用argparse模块实现脚本命令行参数解析 By:授客 QQ:1033553122 #代码实践1 study.py内容如下 #!/usr/bin/env python# -*- coding:ut ...

  • python笔记42-http请求命令行工具(httpie)

    前言 通常我们需要快速的测试某个接口通不通,一般linux上用curl去发http请求,但是这个命令行工具语法有点复杂了,不够直观. python有一个给人类使用的requests库,非常的简单方便. ...

  • Python笔记3:使用命令行运行Python文件

    2021-06-28 17:04:31 csdn_work 码龄5年 使用命令行运行Python文件 1.写Python代码,并保存文件为XX.py: 2.打开cmd代码命令行,输入 cd d/ 文件 ...

  • appium+python自动化44-appium命令行模式

    前言 appium desktop有个客户端版本,每次运行脚本的时候都要去双击启动才能运行,很显然不太方便,影响效率.那么有没什么办法不启动桌面程序就能运行呢,比如cmd命令行执行? 环境: appi ...

  • python笔记16-执行cmd指令(os.system和os.popen)

    os.system 1.如果想在cmd执行python脚本,可以直接用如下指令 python [xx.py绝对路径] 比如我写了个hello.py的脚本,在脚本里面写入内容:print("h ...

  • appium+python自动化60-appium命令行参数

    Appium服务器参数 许多Appium 1.5服务器参数已被弃用,以支持-default-capabilities标志. 用法: node . [flags] help 1.cmd端口输入,appi ...

  • python笔记26-命令行传参sys.argv

    前言 平常我们在用别人写好的python包的时候,在cmd输入xx -h就能查看到帮助信息,输入xx -p 8080就能把参数传入程序里,看起来非常酷. 本篇就来讲下如何在python代码里加入命令行 ...

  • 多个库,多条路,Python 到底有多少命令行参数解析库?

    橡皮擦,一个逗趣的互联网高级网虫. 本篇博客将为你带来 10 个 Python 中的参数解析库,Python 自带的这些[模块军火库],一定要了解,毕竟多掌握一个库,你解决问题的时候就多了一条路. 文 ...

  • 30 行代码带你用 Python 在命令行查看图片

    来源:Python 技术「ID: pythonall」 每次看黑客类的电影时都惊叹于黑客的技术之高超,黑客的手在键盘上飞快的敲击,屏幕上各种字符狂闪不止,接着系统就被黑掉了. 我们都知道黑客在命令行发 ...