一个好的子进程管理需要满足什么功能需求?
- 无阻塞 / 阻塞
- 标准输入 / 输出
- 信号发送 / kill
其实也不多。
开始
1 2 3 4 5 6 |
import subprocess proc = subprocess.Popen('ping 127.0.0.1', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE) print(proc.stdout.read().decode('gbk')) # 因为是 windows 系统,默认编码是 ‘gbk’ |
1 2 3 4 5 6 7 8 9 |
正在 Ping 127.0.0.1 具有 32 字节的数据: 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 127.0.0.1 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 0ms,最长 = 0ms,平均 = 0ms |
subprocess 主要有两个运行命令的方法:
- subprocess.run:阻塞,运行时传入输入,运行结束返回输出;
subprocess.Popen
:无阻塞,是subprocess.run
的底层实现,拥有一切功能。
Popen()
1 2 3 4 5 6 7 8 |
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, group=None, extra_groups=None, user=None, umask=-1, encoding=None, errors=None, text=None) |
可以看到,参数非常之多,但我们一般关注其中几个足矣。
args & shell
args 为子进程命令,默认只能是字符串列表。shell 默认 False,为 True 代表着使用环境变量中默认 shell 来执行 args,这种情况下,可以传入字符串 args。
1 2 |
Popen(['git', 'commit', '-m', 'Fixes a bug.']) Popen('git commit -m Fixs a bug.', shell=True) |
shell=True
其实是有