python-subprocess创建附加进程

本文介绍Python中使用Subprocess模块处理进程的方法,包括启动、管理和获取进程输出等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果你是一名Unix/Linux系统管理员,那么对进程进行处理将会是工作的主要内容。你需要知道启动脚本、运行等级、守护进程、长时间运行的进程以及一大堆相关问题。所幸的是,Python处理进程相当容易。从Python2.4开始,Subprocess已经成为一站式模块,允许你派生出新的进程,并且与标准输入、标准输出以及标准错误输出进行会话。与进程会话是处理进程的一方面,理解如何部署和管理长时间运行的进程也是很重要的。

子进程

Python的Subprocess或许是单一的最重要的模块,它对于shelling out具有统一API。Python中的子进程负责处理下列事物:派生新的进程连接标准输入、连接标准输出、连接错误流、侦听返回码。子进程的一个简单示例:

import subprocess
subprocess.call(['df','-k'], shell = True)

subprocess.call(args*stdin=Nonestdout=Nonestderr=Noneshell=False):父进程等待子进程完成,返回执行状态码。shell = True表示在shell中执行命令,不要将stdout=PIPE或者stdin=PIPE用于该函数,否则可能会因子进程大量输出而导致死锁。

错误处理

call()的返回值是程序的退出码,调用者都要负责解释这个返回值来检测错误。check_call()函数的工作类似于call(),除了检查退出码外,如果发生了错误,则会产生一个CalledProcessError异常。
try:
    subprocess.check_call(['false'])
except subprocess.CalledProcessError as err:
    print 'ERROR:', err

Subprocess捕获标准输出

某些情况下只对系统调用感兴趣,而不关心标准输出。在这种情况下,经常需要禁止Subprocess.call的标准输出,只需将输出定位到/dev/null中即可:

import subprocess
subprocess.call("ping -c 3 www.baidu.com", shell = True, stdout = open('/dev/null'), stderr = subprocess.STDOUT)

如果对shell命令的输出不感兴趣,只是希望程序被运行,可典型的使用Subprocess.call,如果需要得到子进程的运行结果,则可以用subprocess.Popen。在subprocess.call与subprocess.Popen之间,存在一个非常大的差异。subprocess.call会封锁对时间的等待(即会卡住等待子进程运行结束),而subprocess.Popen不会。
p = subprocess.Popen('df -h", shell = True, stdout = subprocess.PIPE)
out = p.stdout.read()
print out
subprocess.check_output()也得到标准输出。
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False,universal_newlines=False):父进程等待子进程完成,返回子进程向标准输出的输出结果,检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try…except…来检查。
try:
    p = subporcess.check_output(['du -sh','/home/'], shell = True)
    print p
except  subprocess.CalledProcessError as err:
    print 'ERROR:',err

使用Subprocess与标准输入进行通信

p = subprocess.Popen("wc -c", shell = True, stdin=subprocess.PIPE)
p.communicate("charactersinword")

输出:16,具有相同功能的Bash代码为:
$ echo charactersinword | wc -c
p.communicate会一直等到进程退出,并将标准输出和标准错误输出返回,这样就可以得到子进程的输出了,另一个例子为:
p = subprocess.Popen('ls', shell = True, stdout = subprocess.PIPE)
stdoutput,stderrput = p.communicate('/home/zoer')
print stdoutput
print stderrput
在Bash中可以用管道连接多个命令,比如:
cat /etc/passwd | grep 0:0 | cut -d ':' -f 7
利用subprocess也可连接多个命令,实现相同的功能:
p1 = subprocess.Popen("cat /etc/passwd", shell = True, stdout = subprocess.PIPE)
p2 = subprocess.Popen("grep 0:0", shell = True, stdin = p1.stdout, stdout = subprocess.PIPE)
p3 = subprocess.Popen("cut -d ':' -f 7", shell = True, stdin = p2.stdout, stdout = subprocess.PIPE)
print p3.stdout.read()
Popen()方法:
  • Popen.poll():检查子进程是否结束,设置并返回return code属性
  • Popen.wait(): 等待子进程结束,设置并返回return code属性
  • Popen.communicate(input=None): 与子进程进行交互,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。
  • Popen.send_signal(signal): 向子进程发送信号
  • Popen.terminate(): 停止(stop)子进程
  • Popen.kill(): 杀死(kill)子进程
  • Popen.pid: 获取子进程的ID
  • Popen.returncode: 获取返回值,如果进程还没结束,就返回None



### 使用 `subprocess.run` 调用 Keil 编译器 为了使用 Python 的 `subprocess.run` 来编译 Keil 项目,需要理解如何构建命令行参数并传递给 Keil 编译工具。通常情况下,Keil 提供了一个名为 UV4 或 uVision 的批处理文件用于自动化编译过程。 下面是一个简单的例子展示如何利用 `subprocess.run` 方法执行此操作: ```python import subprocess def compile_keil_project(project_file, output_log=None): """ 使用 subprocess.run 执行 Keil 编译 参数: project_file (str): .uvprojx 文件路径. output_log (str, optional): 日志保存位置,默认不保存日志. 返回: CompletedProcess 实例表示已完成的过程. """ command = ["UV4", "-b", project_file] if output_log is not None: command.extend(["-jln", output_log]) result = subprocess.run(command, capture_output=True) return result if __name__ == "__main__": proj_path = r"C:\path\to\your\project.uvprojx" log_path = r"C:\path\to\output.log" process_result = compile_keil_project(proj_path, log_path) print(f"Return code: {process_result.returncode}") print("Standard Output:") print(process_result.stdout.decode()) print("\nStandard Error:") print(process_result.stderr.decode()) ``` 这段代码定义了一个函数 `compile_keil_project()` ,它接受两个参数:一个是 `.uvprojx` 格式的工程文件路径;另一个是可选的日志输出路径。该函数会返回一个包含进程运行结果的对象[^1]。 #### 函数说明 - **command**: 构建了要发送到 shell 的指令列表。这里包含了启动 Keil 编译所需的最少选项 `-b`(build),以及当指定了日志文件时附加的 `-jln` 选项。 - **capture_output=True**: 表明希望捕获标准输出和错误流以便后续分析或显示。 - **result**: 存储由 `subprocess.run` 创建的结果对象,其中包含了关于子进程中发生的事情的信息,比如退出状态码(`returncode`) 和任何产生的输出 (`stdout`, `stderr`)。 注意,在实际应用中可能还需要考虑更多细节,例如设置工作目录、环境变量等,具体取决于项目的配置和个人需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值