Python调用Shell命令 (python, shell 混合编程)

举报
python教程 发表于 2024/04/28 16:31:56 2024/04/28
【摘要】 ​Python经常被称作“胶水语言”,因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库,也当然可以用Python调用Shell命令。用Python调用Shell命令有如下几种方式: 1. os.systemos.system("The command you want").os.system("lscpu").os.system("ls -al").这个调用相当直接,且是同步进行...

​Python经常被称作“胶水语言”,因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库,也当然可以用Python调用Shell命令。

用Python调用Shell命令有如下几种方式:

1. os.system

os.system("The command you want").
os.system("lscpu").

os.system("ls -al").

这个调用相当直接,且是同步进行的,程序需要阻塞并等待返回。返回值是依赖于系统的,直接返回系统的调用返回值,所以windows和linux是不一样的。

2. os.popen

os.popen(command[,mode[,bufsize]])

请在此添加图片描述

可以看出,popen方法通过p.read()获取终端输出,而且popen需要关闭close().当执行成功时,close()不返回任何值,失败时,close()返回系统返回值. 可见它获取返回值的方式和os.system不同。

3. 使用commands ( python3失效)

根据你需要的不同,commands模块有三个方法可供选择。getstatusoutput, getoutput, getstatus。

commands.getstatusoutput(cmd) #返回(status, output).
commands.getoutput(cmd) #只返回输出结果
commands.getstatus(file) #返回ls -ld file的执行结果字符串,调用了getoutput,不建议使用此方法

但是,如上三个方法都不是Python推荐的方法,而且在Python3中其中两个已经消失。

4. subprocess《Python文档中目前全力推荐》

subprocess使用起来同样简单:

直接调用命令,返回值即是系统返回。shell=True表示命令最终在shell中运行。Python文档中出于安全考虑,不建议使用shell=True。建议使用Python库来代替shell命令,或使用pipe的一些功能做一些转义。官方的出发点是好的,不过真心麻烦了很多, so…

但是,我使用subprocess失败了

>>> import subprocess
>>> subprocess.call("cat %s |grep %s > %s " % ("/home/www/running/os-app-api/nohup.out","2019-10-28","~/nohup-2019-10-28.out"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.6/subprocess.py", line 287, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/lib64/python3.6/subprocess.py", line 729, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.6/subprocess.py", line 1364, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'cat /home/www/running/os-app-api/nohup.out |grep 2019-10-28 > ~/nohup-2019-10-28.out ': 'cat /home/www/running/os-app-api/nohup.out |grep 2019-10-28 > ~/nohup-2019-10-28.out '

请在此添加图片描述
但是,可以直接运行在shell里面:

请在此添加图片描述
同样的 我用os.system 去运行,也确实产生了。

>>> import os
>>> os.system("cat %s |grep %s > %s " % ("/home/www/running/os-app-api/nohup.out","2019-10-28","~/nohup-2019-10-28.out"))

256

源码研究:

请在此添加图片描述
这里面最为重要的几个参数是:.

  • args:要执行的shell命令,或者是命令的列表;
  • bufsize:缓冲区大小;。
  • stdin、stdout、stderr:表示程序的标准输入、标准输出以及错误输出。
  • shell:是否直接执行命令,如果设置为True就表示可以直接执行;
  • cwd:当前的工作目录;
  • env:子进程环境变量;

请在此添加图片描述
subprocess模块里面还有一项功能比较强大的支持在于可以直接使用标准输入、标准输出和错误输出进行进程的数据通讯操作。

例如,在Python安装完成之后都会存在有交互式的编程环境,那么本次将通过程序调用交互式编程环境直接操作python命令行,在python命令行中直接输入程序。

def main():
#学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
    subp_popen=subprocess.Popen("python.exe",stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
 
    subp_popen.stdin.write("print('subp_popen.stdin.write1')\n".encode())
    subp_popen.stdin.write("print('subp_popen.stdin.write2')\n".encode())
    subp_popen.stdin.write(("print('subp_popen.stdin.write3'+1)").encode())
    subp_popen.stdin.close()
 
    cmd_out=subp_popen.stdout.read()
    subp_popen.stdout.close()
    print(cmd_out.decode())
 
    cmd_err=subp_popen.stderr.read()
    subp_popen.stderr.close()
    print(cmd_err)
 
if __name__ == '__main__':
 
    main()

请在此添加图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。