子进程
什么是子进程
当前正在执行的程序叫做主进程,比如你运行 python xxx.py。
任何进程(包括“主进程”自己)要跑外部工具(git、ffmpeg、ls等等外部程序),都必须启动一个“子进程”来跑它,python内置了开启子进程方法 subprocess!
如获取当前目录信息,在linux上是终端执行 ls -l,而如下代码则是代替你执行这个操作。
再比如调用新的进程执行python,甚至其它程序。
参数
capture_output
捕获原始输出(默认情况下执行ls -l 的输出会直接打印到“当前进程的终端/控制台”上,这个就是原始输出),捕获之后原始将不再输出,进而被抓到返回值里去了
执行结果
stdout与stderr
调用 subprocess.run() 时,会返回一个 CompletedProcess 对象(表示该子进程已经执行完成的结果快照),其中常用属性有:
result.stdout:子进程的标准输出(standard output)result.stderr:子进程的标准错误输出(standard error)
提示
约定俗成的用法(程序员一般会这么做):
- 正常结果一般写到
stdout(如对应自己编程中 console.log) - 错误信息、警告等一般写到
stderr(如对应自己编程中 console.error)
但这只是惯例,不强制,成功时也可能有 stderr 输出,失败时也可能往 stdout 输出。
因为操作系统只负责给进程准备三个管道:stdin标准输入、stdout标准输出、stderr标准错误,
它不决定写什么内容,也不决定“啥是成功/失败”。
系统只是把进程写入 stdout/stderr 的内容送到对应的地方(终端、管道、被 Python/Node 读取等)。
- C 程序里printf() 默认写到 stdout,fprintf(stderr, "err") 写到 stderr
- Python 里:print() 默认写到 sys.stdout,print(..., file=sys.stderr) 写到 stderr
- Node 里是你/库调用 console.log / console.error
- Java 里:System.out.println() 写到 stdout,System.err.println() 写到 stderr
- 各种命令行工具(git、ls、curl、npm、node 自己)内部也会写 stdout/stderr
returncode
res.returncode 是子进程的退出码(exit code),用来表示这个命令/程序最后是怎么结束的,通常 0 表示成功,非 0 表示失败,以 Python 举例:
提示
谁设的这个数字?同样也有约定俗成,在子进程里由程序自己决定的。
- C:
return 0;/return 1;/exit(1); - Python:
sys.exit(0)/sys.exit(1) - Node:
process.exit(0)/process.exit(1)
父进程只是把这个数字取出来放到 result.returncode,方便判断命令是否“成功”:
- “成功/失败”主要看
returncode - 输出内容是什么,主要看
stdout/stderr写了什么
来个实际例子
单元测中 利用断言,来让子进程收集错误信息
other_script.py
run_test.py
最终控制台输出如下

