CommandLib
Commandlib 是一个无依赖库,用于以干净、可读的方式在构建脚本中调用外部 UNIX 命令(例如)。
使用方法链接,你可以构建 Command 对象,这些对象在特定目录中运行,并具有指定的环境变量和PATH等。
为了简单起见,该库本身只以阻塞方式运行命令(所有命令在继续之前都运行到完成),尽管它包含通过icommandlib或pexpect运行非阻塞命令的钩子。
假装“django/manage.py”
# Pretend django "manage.py" that just prints out arguments:
import sys ; sys.stdout.write(' '.join(sys.argv[1:]))
from commandlib import Command
# Create base command
python = Command("python")
# Create command "python manage.py" that runs in the django directory
manage = python("manage.py").in_dir("django")
# Build even more specific command
dev_manage = manage.with_trailing_args("--settings", "local_settings.py")
# Run combined command
dev_manage("runserver", "8080").run()
将输出
runserver 8080 --settings local_settings.py
安装
$ pip install commandlib
文档
- 将目录添加到 PATH (with_path)
- 捕获输出 (.output())
- 从一个目录轻松调用命令 (CommandPath)
- 更改命令的环境变量 (with_env)
- 运行命令,在非零退出代码时不引发异常 (ignore_errors())
- 从字符串或文件管道输入数据 (.piped)
- 将数据管道输出到字符串或文件 (.piped)
- 使用 icommandlib 或 pexpect 交互式地运行命令
- 从当前虚拟环境轻松调用命令 (python_bin)
为什么?
Commandlib 避免了直接使用 subprocess 库(Popen、call、check_output()、.communicate() 等)以及由此产生的混淆而导致的混乱代码。
这是一个高度狗粮的库。
subprocess 真的有那么糟糕吗?
代码可能会更长、更乱。例如,来自堆栈溢出
import subprocess, os
previous_directory = os.getcwd()
os.chdir("command_directory")
my_env = os.environ.copy()
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
os.chdir(previous_directory)
等同于
from commandlib import Command
Command(my_command).with_path("/usr/sbin:/sbin:").in_dir("command_directory").run()
为什么不使用 Delegator(Kenneth Reitz 的“面向人类的子进程”)?
Kenneth Reitz(requests 的作者,“面向人类的 urllib2/3”)编写了一个类似的“面向人类的子进程”,称为envoy。现在已弃用,现在有一个称为delegator的替代方案,它是一个非常薄的 subprocess 包装器。
delegator 具有而 commandlib 没有的功能
-
Delegator 可以像 bash 一样链接命令(delegator.chain('fortune | cowsay'))。Commandlib 不这样做,因为在对该库进行狗粮测试时,我从未遇到过需要这样做的情况。但是,你可以很容易地使用 .output() 获取一个命令的输出作为字符串,并使用 piped.from_string(string) 将其馈送到另一个命令中。
-
Delegator 以阻塞和非阻塞方式运行子进程(使用 pexpect)。commandlib 本身只执行阻塞,但如果你 pip install pexpect 或 icommandlib,它可以通过其中任何一个运行。
-
在 Windows 上运行
两者都具有的功能
- 能够设置环境变量。
- 能够从命令对象运行 pexpect 进程。
commandlib 独有的功能
- 能够轻松地设置 PATH。
- 能够轻松地从当前虚拟环境调用代码。
- 能够管道输入字符串或文件,以及轻松地将管道输出到字符串或文件(或文件句柄)。
- 用于从当前虚拟环境轻松运行命令的钩子。