Python中os.system()、subprocess.run()、call()、check_output()的用法

2023-07-06 21:21:21 来源:博客园

1.os.system()

os.system() 是对 C 语言中 system() 系统函数的封装,允许执行一条命令,并返回退出码(exit code),命令输出的内容会直接打印到屏幕上,无法直接获取。

示例:


(资料图)

# test.pyimport osos.system("ls -l | grep test")    # 允许管道符# 测试执行$ ll                <======== 列出当前目录中的内容drwxr-xr-x 2 foo foo 4096 Feb 13 09:09 __pycache__-rw-r--r-- 1 foo foo  359 Feb 19 09:21 test.py$ python test.py-rw-r--r-- 1 foo foo  359 Feb 19 09:21 test.py    <======== 只有名字包含 test 的文件被列出

2.subprocess.run()

Python 3.5 开始推荐使用这个方法执行命令,其原型如下:

subprocess.run(    args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False,     shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None,     text=None, env=None, universal_newlines=None)

其中:

  • args: 可以是一个字符串(当 shell=True 时),也可以是一个列表(当 shell=False 时)

  • stdin, stdout, stderr: 用于指定标准IO文件句柄,可以是:

    subprocess.PIPE: 用作 stdout, stderr 参数的值时,可以从返回值对象中的 stdout 和 stderr 属性中读取输出内容  subprocess.STDOUT: 用作 stderr 参数的值时,相当于把标准错误重定向到标准输入中)  subprocess.DEVNULL: 用作 stdout, stderr 参数的值时,相当于把输出内容重定向到 /dev/null  用户已经打开的文件对象或描述符(整型数字)
  • capture_output: 当设置为 True 时,相当于 stdout 和 stderr 参数都设置为 True 了,可以通过返回值对象访问标准输出和标准错误内容

  • shell: 当设置为 True 时,args 参数会当做一条命令字符串(支持管道、重定向操作);当它为 False 时,args 需是一个列表(并且不支持管道、重定向操作)

  • cwd: 指定执行命令的目录,默认为当前目录

  • timeout: 指定命令执行超时时间(按妙计),若执行超时了,会 kill 掉命令并抛出 TimeoutExpired 异常

  • check: 当设置为 True 时,会自动检测执行退出码,若不为0,则抛出 CalledProcessError 异常

  • text: 当设置为 True 时,stdin、stdout、stderr 会以“文本”模式打开(返回值对象中的 stdout、stderr 存储文本内容),否则返回值对象中 stdout、stderr 存储的是字节序列

  • env: 用于设置程序执行时继承的环境变量等,默认与当前进程相同

该方法返回一个 CompletedProcess 对象,其中包含以下属性:

  • returncode: 执行命令的退出码
  • stdout: 捕获的标准输出内容(当 stdout 参数为 PIPE 时)。其格式默认为字节序列,除非 text 参数为 True (此时为文本格式)。
  • stderr: 捕获的标准错误内容(当 stderr 参数为 PIPE 时)。其格式默认为字节序列,除非 text 参数为 True (此时为文本格式)。
  • args: 同参数 args 。

示例:

import subprocesssubprocess.run(["ls", "-l"])            # 默认时,args 参数需是一个列表subprocess.run("ls -l", shell=True)     # 当 shell 为 True 时,args 是一个字符串ret = subprocess.run("ls -l", shell=True, capture_output=True, text=True) # 以文本模式捕获输出内容print("Return code:", ret.returncode)   # Return code: 0print("STDOUT:", ret.stdout)            # STDOUT: ...当前目录内容...print("STDERR:", ret.stderr)            # STDERR: <空>ret = subprocess.run("abcdefg", shell=True, text=True,  # 注意:这里必须 shell=True 才能捕获到 /bin/sh 的输出错误        # 当 shell=False 时,是要去捕获 "abcdefg" 命令自身输出的内容,但是它不存在,python 会报错    stdout=subprocess.PIPE, stderr=subprocess.STDOUT    # 标准错误重定向到标准输出) print("STDOUT:", ret.stdout)            # STDOUT: /bin/sh: abcdefg: command not found

另一个用于测试 shell 参数区别的示例如下:

import sys, re, subprocessif len(sys.argv) == 1:  # parent process    cmd = ["python", sys.argv[0], "--run-child"]        ret = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)    print(ret) # CompletedProcess(args=["python", "test.py", "--run-child"], returncode=0, stdout="stdout output\n", stderr="stderr output")    assert re.match("stdout output", ret.stdout)    assert re.match("stderr output", ret.stderr)    # 如果 cmd 中的命令不存在,这里是捕获不到的,subprocess.run()自己就会报错        ret = subprocess.run(" ".join(cmd), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)    print(ret) # CompletedProcess(args="python test.py --run-child", returncode=0, stdout="stdout output\n", stderr="stderr output")    assert re.match("stdout output", ret.stdout)    assert re.match("stderr output", ret.stderr)    # 如果 cmd 中的命令不存在,这里也是可以捕获到的,内容可能是 xxx command not found        print("Passed!")else:                   # child process    print("stdout output")    sys.stderr.write("stderr output")

3.subprocess.call()

Python 3.5 以前(包括 2.x 版本)没有 subprocess.run() 方法,可以使用 subprocess.call() 来执行命令,该方法原型如下:

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None)

注意:这个方法的返回值是命令的退出码,而不是一个对象,所以无法像 subprocess.run() 一样捕获命令输出内容(不要设置 stdout=PIPE 或 stderr=PIPE,否则可能造成命令卡死)。

该方法的其它参数与 subprocess.run() 类似。

4.subprocess.check_output()

Python 3.5 以前的版本,要想捕获命令输出内容,可以使用 subprocess.check_output() 方法,它的原型如下:

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=None, timeout=None, text=None)

注意:参数中没有 stdout ,因为这个函数的返回值默认就是标准输出内容,也可以将设置 stderr=subprocess.STDOUT 将标准错误重定向到标准输出,但是好像没有办法单独捕获标准错误内容呢!

示例:

import sys, re, subprocess#Python小白学习交流群:711312441if len(sys.argv) == 1:  # parent process    cmd = ["python", sys.argv[0], "--run-child"]    ret = subprocess.check_output(cmd, stderr=subprocess.STDOUT)    print("[" + ret + "]")  # 输出内容中包含标准输出和标准错误,输出顺序在 windows 下和 linux 下可能会有差异    assert re.search("stdout output", ret)    assert re.search("stderr output", ret)    print("Passed!")else:                   # child process    print("stdout output")    sys.stderr.write("stderr output")

标签

郴州安仁文旅项目集中开工 总投资1000万元

3月16日,安仁县举行文旅项目集中开工活动,县委书记王洪灿在开工仪式上宣布:湘南起义旧址群——朱毛井...

2022-03-20 15:40:46

2022年郴州计划重点推进文旅项目101个 总投资354亿元

3月16日,我市举行全市文旅项目和城市大提质大融城项目集中开工仪式,市委书记吴巨培宣布项目开工。郴州...

2022-03-20 15:39:41

宿州泗县深入推进文旅融合发展 擦亮城市品牌

近年来,泗县以争创安徽省文化旅游名县为目标,深入推进文旅融合发展,努力擦亮水韵泗州 运河名城城市...

2022-03-20 15:38:59

汽车零部件产业“领头羊” 锦州力争一季度“开门红”

3月16日,记者从锦州汽车零部件产业的领头羊——锦州万得集团获悉,今年前两个月,企业订单充足,正铆足...

2022-03-20 15:37:41

油价或有望冲击“九元”大关 宁波新能源汽车市场如何

新一轮国内成品油调价窗口于3月17日24时开启,油价或有望冲击九元大关。前一天晚上11点,鄞州区不少加油...

2022-03-20 15:34:38

从水塘到“云”端 全国最大高邮鸭养殖基地实现智慧养殖

随着新一代数字技术的蓬勃发展,以新兴技术推动现代化新农村建设正成为助力乡村振兴的重要手段。1个人能...

2022-03-20 15:33:17

淡季不忘引流 京郊民宿市场有望迎来回暖

旅游淡季中的京郊民宿有望成为市场中最先复苏的板块。3月17日,北京商报记者调查发现,虽然正值旅游淡季...

2022-03-20 15:32:01

镇江乡村一二三产业融合发展 闯出“镇江之路”

从烹饪江鲜河豚的个体小饭店到规模化的江岛乡村旅游产业集群,从白兔草莓丁庄葡萄的单个农户种植到茅山...

2022-03-20 15:31:11

总投资30亿元 盐城东台8个重大产业项目相继开工

总投资30亿元的精密电子元器件项目、同益电子项目,总投资10亿元的金利美精密组件项目、天永智能设备项...

2022-03-20 15:30:13

去年南京规上信息软件业企业实现营收7577.28亿元 同比增长10.3%

市统计局最新统计数据显示,2021年,我市规模以上信息软件业企业共1662家,较上年同期增加321家,实现营...

2022-03-20 15:28:57
x 广告
x 广告

Copyright  2015-2022 太平洋粮油网版权所有  备案号:豫ICP备2022016495号-17   联系邮箱:93 96 74 66 9@qq.com