文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python subprocess模块

2023-01-31 06:56

关注

subprocess模块

允许你生成一个或多个进程,并且可以跟它交互,并且获取返回的结果,这个模块想要替换掉几个老的方法:
        os.system
        os.spawn*
        所以以后跟系统交互的命令,尽量用subprocess

建议调用subprocess的run()方法去跟系统进行调用,更高级的方法,使用popen() ;run()方法其实就是封装的popen。

run()方法在python3.5才有,python2.x没有,2.x用subprocess.call(),当然python3.X版本也支持call()

常见的subprocess方法

subprocess.call
    subprocess.call("df -lh",shell=True) 或者 subprocess.call(["df","-lh"])
    如果想获取到执行内容:
         a = subprocess.Popen("df -lh",shell=True,stdout=subprocess.PIPE)
         a.stdout.read()

subprocess.check_call
    执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
    subprocess.check_call(["ls","-l"])
    subprocess.check_call("exit 1",shell=True)   抛出异常:subprocess.CalledProcessError:

subprocess.check_output
    执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
    subprocess.check_output(["echo","hello world!"])    返回:'hello world!\n'
    subprocess.check_output("exit 1",shell=True)        剖出异常:subprocess.CalledProcessError
    执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res
    res = subprocess.getoutput("ls /bin/sh")
    res     输出:'/bin/sh'

subprocess.getstatusoutput
    接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果
    subprocess.getstatusoutput("ls /bin/ls")        返回:(0, '/bin/ls')

subprocess.getoutput
    接收字符串格式命令,并返回结果
    subprocess.getoutput("ls /bin/ls")      返回:'/bin/ls'

上边的subprocess方法,底层都是封装的subprocessPopen

subprocess的其他解说:

poll()
    Check if child process has terminated. Returns returncode
wait()
    Wait for child process to terminate. Returns returncode attribute.

terminate() 杀掉所启动进程
communicate() 等待任务结束

stdin 标准输入
stdout 标准输出
stderr 标准错误

pid
    The process ID of the child process.

Popen例子:
    p = subprocess.Popen("df -lh|grep root",stdin=subproce
    p.stdout.read()     输出:b'/dev/mapper/cl-root   38G  5.7G   32G  16% /\n'

run()方法的使用:

    subprocess.run(["ls","-lh"])
    subprocess.run("exit 1",shell=True,check=True)  抛出异常:subprocess.CalledProcessError
    subprocess.run(["ls","-l","/dev/null"],stdout=subprocess.PIPE) 输出:
    如下:CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw-. 1 root root 1, 3 Jan  3 11:16 /dev/null\n')

调用和系统之间的操作,推荐subprocess.run() ,因为它迟早要替换掉sys.system ;
run()方法可以满足大部分的需求,如果要进行一些复杂的交互的话,还可以用subprocessPopen()
如:
    p = subprocess.Popen("find / -size +1000000 -exec ls -shl {} \;",shell=True,stdout=subprocess.PIPE)
    print (p.stdout.read())
    输出:b'0 -r--------. 1 root root 128T Jan 23 14:58 /proc/kcore\n1.9G -rw-------. 1 root root 100G Jan  8 17:48 /var/lib/docker/devicemapper/devicemapper/data\n3.8M -rw-------. 1 root root 2.0G Jan  8 17:48 /var/lib/docker/devicemapper/devicemapper/metadata\n'

subprocess.Popen(...)

    用于执行复杂的系统命令

    参数:
    args:shell命令,可以是字符串或者序列类型(如:list,元组)
    bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
    stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
    preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
    close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
    所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
    shell:同上
    cwd:用于设置子进程的当前目录
    env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
    universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
    startupinfo与createionflags只在windows下有效
    将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

终端输入的命令分为两种:
    输入即可得到输出:如 ifocnfig
    输入进行某环境,依赖某环境再输入:如 python

需要交互的命令示例:
    import subprocess
    obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    obj.stdin.write('print 1 \n ')
    obj.stdin.write('print 2 \n ')
    obj.stdin.write('print 3 \n ')  #当从这里开始就报错了。
    obj.stdin.write('print 4 \n ')

    out_error_list = obj.communicate("timeout=10")
    print out_error_list
    输出:
        ('', '  File "<stdin>", line 2\n    print 2 \n    ^\nIndentationError: unexpected indent\n')

subprocess实现iptables 清规则的时候 sudo 自动输入密码

    import subprocess
    def mypass():
        mypass = '123'  # or get the password from anywhere
        return mypass
    echo = subprocess.Popen(['echo', mypass()],
                            stdout=subprocess.PIPE,
                            )
    sudo = subprocess.Popen(['sudo', '-S', 'iptables', '-L'],
                            stdin=echo.stdout,
                            stdout=subprocess.PIPE,
                            )
    end_of_pipe = sudo.stdout

    print ("Password ok \n Iptables Chains %s" % end_of_pipe.read())
阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯