跳转到主要内容

程序友好型子进程包装器

项目描述

https://travis-ci.org/xolox/python-executor.svg?branch=master https://coveralls.io/repos/xolox/python-executor/badge.png?branch=master

executor 包是一个简单的Python的 subprocess 模块的包装器,使得在UNIX系统上处理子进程变得非常容易,具有适当的参数转义和错误检查。

  • 使用面向对象接口执行命令,默认值合理且可定制(并且有良好的文档说明)。

  • 支持使用相同的面向对象接口执行远程命令(通过 SSH 执行),以及 chroot 内的命令(使用 schroot 执行)。

  • 还支持在所谓的“命令池”中并发执行一组命令。并发级别可以自定义,当然,本地和远程命令都得到支持。

该包目前在Python 2.6、2.7、3.4、3.5、3.6和PyPy上进行了测试。有关使用说明,请参阅以下部分和 文档

安装

executor》软件包可在PyPI上获取,这意味着安装应该非常简单:

$ pip install executor

实际上,安装Python软件包有多种方式(例如,个人站点的包目录虚拟环境或全局安装),在这里我不想深入讨论这个问题。所以,如果你感到害怕,请在返回这些说明之前先了解一下你的选项;-)

使用

使用《executor》软件包有两种方法:作为命令行程序 executor 和作为Python API。下面将描述命令行界面,并且还有一些Python API的简单用例。

命令行

用法: executor [OPTIONS] COMMAND …

基于同名Python包的命令行子进程管理。该“executor”程序运行外部命令,支持超时、动态启动延迟(调整因子)和独占锁定。

您可以将“executor”视为“flock”和“timelimit”程序的组合,具有一些额外的好处(尤其是动态启动延迟和UNIX平台上的集成系统日志)。

支持选项

选项

描述

-t--timeout=LIMIT

设置给定命令将被中止的时间。默认情况下 LIMIT 以秒计算。您还可以使用后缀“s”(秒)、“m”(分钟)、“h”(小时)或“d”(天)。

-f--fudge-factor=LIMIT

此选项控制动态启动延迟(调整因子),这在您希望周期性任务在给定间隔内运行一次,但确切时间不重要时很有用。有关 LIMIT 的可接受值,请参阅 --timeout 选项,此数字指定在运行命令之前睡眠的最长时间(最短时间为零,否则您可以在命令行中包含“sleep N && …”命令)。

-e--exclusive

使用进程间锁定文件,以确保executor永远不会并发运行外部命令。有关阻塞/非阻塞行为的自定义,请参阅 --lock-timeout 选项。要自定义锁定文件名称,可以使用 --lock-file 选项。

-T--lock-timeout=LIMIT

默认情况下,executor尝试获取锁定,如果失败,则退出并返回非零退出代码。此选项可用于启用阻塞行为。有关 LIMIT 的可接受值,请参阅 --timeout 选项。

-l--lock-file=NAME

自定义锁定文件名称。默认情况下,这是外部命令的基本名称,因此如果您运行的是类似于“bash”或“python”的通用命令,您可能希望更改此名称。

-v--verbose

增加日志详细程度(可重复)。

-q--quiet

减少日志详细程度(可重复)。

-h--help

显示此消息并退出。

Python API

以下是 execute() 函数多功能性的几个示例。有关更多用例,请参阅 Read the Docs 上的 API 文档。

检查状态码

默认情况下,外部命令的状态码作为布尔值返回

>>> from executor import execute
>>> execute('true')
True

如果外部命令以非零状态码退出,则会引发异常,这使得执行正确的事情变得容易(无需编写大量重复代码即可检查外部命令的状态码)

>>> execute('false')
Traceback (most recent call last):
  File "executor/__init__.py", line 124, in execute
    cmd.start()
  File "executor/__init__.py", line 516, in start
    self.wait()
  File "executor/__init__.py", line 541, in wait
    self.check_errors()
  File "executor/__init__.py", line 568, in check_errors
    raise ExternalCommandFailed(self)
executor.ExternalCommandFailed: External command failed with exit code 1! (command: bash -c false)

ExternalCommandFailed 异常公开了 commandreturncode 属性。如果您知道一个命令很可能以非零状态码退出,并且您希望 execute() 仅返回布尔值,则可以这样做

>>> execute('false', check=False)
False

提供输入

以下是如何向外部命令提供输入的示例

>>> execute('tr a-z A-Z', input='Hello world from Python!\n')
HELLO WORLD FROM PYTHON!
True

获取输出

获取外部命令的输出也非常简单

>>> execute('hostname', capture=True)
'peter-macbook'

以 root 身份运行命令

以超级用户权限执行命令也非常简单

>>> execute('echo test > /etc/hostname', sudo=True)
[sudo] password for peter: **********
True
>>> execute('hostname', capture=True)
'test'

启用日志记录

如果您想知道在命令前加上 sudo 会如何有所帮助,以下是它的工作原理

>>> import logging
>>> logging.basicConfig()
>>> logging.getLogger().setLevel(logging.DEBUG)
>>> execute('echo peter-macbook > /etc/hostname', sudo=True)
DEBUG:executor:Executing external command: sudo bash -c 'echo peter-macbook > /etc/hostname'

运行远程命令

要使用 SSH 在远程系统上运行命令,您可以使用 RemoteCommand 类,它的工作方式如下

>>> from executor.ssh.client import RemoteCommand
>>> cmd = RemoteCommand('localhost', 'echo $SSH_CONNECTION', capture=True)
>>> cmd.start()
>>> cmd.output
'127.0.0.1 57255 127.0.0.1 22'

并行运行远程命令

foreach() 函数封装了 RemoteCommandCommandPool 类,以便于在主机组上并行运行远程命令

>>> from executor.ssh.client import foreach
>>> from pprint import pprint
>>> hosts = ['127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4']
>>> commands = foreach(hosts, 'echo $SSH_CONNECTION')
>>> pprint([cmd.output for cmd in commands])
['127.0.0.1 57278 127.0.0.1 22',
 '127.0.0.1 52385 127.0.0.2 22',
 '127.0.0.1 49228 127.0.0.3 22',
 '127.0.0.1 40628 127.0.0.4 22']

联系方式

executor 的最新版本可在 PyPIGitHub 上获得。文档托管在 Read the Docs 上,包括一个 变更日志。有关错误报告,请创建 GitHub 上的问题。如果您有任何问题、建议等,请随时通过 peter@peterodding.com 发送电子邮件。

许可证

此软件根据 MIT 许可证 许可。

© 2018 Peter Odding。

项目详情


下载文件

下载适合您平台的文件。如果您不确定要选择哪个,请了解更多关于 安装包 的信息。

源分发

metabolexecutor-20.0.post1.tar.gz (88.5 kB 查看散列)

上传时间

支持