zoukankan      html  css  js  c++  java
  • python之subprocess

    官网介绍:https://docs.python.org/3/library/subprocess.html

    Popen():
    [root@oracle scripts]# cat sub_popen.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.Popen(['ls','-l'],shell=True)
    print(type(child))
    print('parent')
    [root@oracle scripts]# python sub_popen.py 
    <class 'subprocess.Popen'>
    parent
    stu_subprocess.py  sub_popen.py
    
    如果将不添加shell,使用默认的:
    [root@oracle scripts]# cat sub_popen.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.Popen(['ls','-l'],shell=False)      shell参数默认为False
    print(type(child))
    print('parent')
    [root@oracle scripts]# python sub_popen.py 
    <class 'subprocess.Popen'>
    parent
    total 8
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 136 Aug 21 15:41 sub_popen.py
    
    Popen不会阻塞父进程运行,Popen启动新的进程与父进程并行执行,默认父进程不等待新进程结束。
    [root@oracle scripts]# cat test_subprocess.py
    #!/usr/bin/python
    #coding=utf8
     
    def TestPopen():
    import subprocess
    p = subprocess.Popen(['ls','-l'],shell=True)
    for i in range(5):
    print("other things")
     
    print(TestPopen())
    [root@oracle scripts]# python test_subprocess.py
    other things
    other things
    other things
    other things
    other things
    None
    stu_subprocess.py sub_call.py sub_check_output.py sub_popen.py sub_run.py test_subprocess.py
     
    [root@oracle scripts]# cat test_subprocess1.py
    #!/usr/bin/python
    #coding=utf8
     
    wait(): 阻塞父进程,等待子进程运行结束再继续运行父进程
    def TestWait():
    import subprocess
    import datetime
    print(datetime.datetime.now())
    p = subprocess.Popen('sleep 10',shell=True)
    p.wait() wait()阻塞了父进程的运行,等待子进程运行完成后才继续运行父进程
    print(p.returncode)
    print(datetime.datetime.now())
     
    TestWait()
    [root@oracle scripts]# python test_subprocess1.py
    2017-08-21 16:49:15.061676
    0 当子进程运行完成结束后,返回code为0
    2017-08-21 16:49:25.066657
     
    poll():判断子进程是否结束
    [root@oracle scripts]# cat test_subprocess2.py
    #!/usr/bin/python
    #coding=utf8
     
    def TestWait():
    import subprocess
    import datetime,time
    print(datetime.datetime.now())
    p = subprocess.Popen('sleep 10',shell=True) 子进程要睡眠10秒
    t = 1
    while (t <= 5):
    time.sleep(1)
    p.poll() 执行判断子进程,这里花了5秒
    print(p.returncode)
    t = t + 1
    print(datetime.datetime.now())
     
    TestWait()
    [root@oracle scripts]# python test_subprocess2.py
    2017-08-21 16:56:33.672417
    None
    None
    None
    None
    None
    2017-08-21 16:56:38.684795
     
    kill()或者terminate(): 杀掉子进程
    [root@oracle scripts]# cat test_subprocess3.py
    #!/usr/bin/python
    #coding=utf8
     
    def TestKillAndTerminate():
    import subprocess
    import datetime,time
    print(datetime.datetime.now())
    p = subprocess.Popen('sleep 10',shell=True)
    t = 1
    while (t <= 5):
    time.sleep(1)
    t = t + 1
    p.kill()
    print(datetime.datetime.now())
     
    TestKillAndTerminate()
    [root@oracle scripts]# python test_subprocess3.py
    2017-08-21 17:03:16.315531
    2017-08-21 17:03:21.329266
    可以看见子进程只运行了5秒
    [root@oracle scripts]# cat sub_popen.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.Popen(['ls','-l'],shell=False)
    child.wait()               阻塞父进程,直到子进程运行完成
    print(type(child))
    print('parent')
    [root@oracle scripts]# python sub_popen.py 
    total 12
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 135 Aug 21 15:47 sub_call.py
    -rw-r--r-- 1 root root 149 Aug 21 15:47 sub_popen.py
    <class 'subprocess.Popen'>
    parent
    可以看出先运行的子进程,最后才是父进程,等待子进程运行后,再运行父进程
    除了wait()之外还有如下:
    child.poll() # 检查子进程状态
    child.kill() # 终止子进程
    child.send_signal() # 向子进程发送信号
    child.terminate() # 终止子进程
    子进程的PID存储在child.pid
    子进程的标准输入、标准输出和标准错误如下属性分别表示:
    child.stdin
    child.stdout
    child.stderr
    
    subprocess.PIPE实际上为文本流提供一个缓存区。child的stdout将文本输出到缓存区,然后打印出缓存区的内容:
    [root@oracle scripts]# cat sub_popen.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.Popen(['ls','-l'],shell=False,stdout=subprocess.PIPE)
    print(child.stdout.read().decode('utf-8'))      打印缓存区内容,由于是bytes格式,所以转码
    print('parent')
    [root@oracle scripts]# python sub_popen.py 
    total 16
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 148 Aug 21 15:53 sub_call.py
    -rw-r--r-- 1 root root 183 Aug 21 16:07 sub_popen.py
    -rw-r--r-- 1 root root 147 Aug 21 15:56 sub_run.py
    
    parent
    
    communicate()
    Popen.communicate(input=None):与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。
    [root@oracle scripts]# cat sub_popen.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.Popen(['ls','-l'],shell=False,stdout=subprocess.PIPE)
    #print(child.stdout.read().decode('utf-8'))
    print(child.communicate())          返回的是标准输出,标准错误输出的tuple
    print('parent')
    [root@oracle scripts]# python sub_popen.py 
    (b'total 16
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 148 Aug 21 15:53 sub_call.py
    -rw-r--r-- 1 root root 211 Aug 21 16:11 sub_popen.py
    -rw-r--r-- 1 root root 147 Aug 21 15:56 sub_run.py
    ', None)    NONE就是标准错误输出结果
    parent
    可以看见先输出的子进程内容,然后才是父进程,communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成
    [root@oracle scripts]# cat sub_popen.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child1 = subprocess.Popen(['cat','/etc/passwd'],shell=False,stdout=subprocess.PIPE)
    child2 = subprocess.Popen(['grep','0:0'],stdin=child1.stdout, stdout=subprocess.PIPE)
    #  subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
    out,err = child2.communicate()   因为communicate()返回的是一个元祖
    print(out)     纸打印出标准输出内容
    print('parent')
    [root@oracle scripts]# python sub_popen.py 
    b'root:x:0:0:root:/root:/bin/bash
    '
    parent
    
    child1.stdout-->subprocess.PIPE
    child2.stdin<--subprocess.PIPE
    child2.stdout-->subprocess.PIPE
    
    利用communicate()实现交互:
    [root@oracle scripts]# cat stu_subprocess.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child1 = subprocess.Popen(['python'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    out,err = child1.communicate(b'print("hello")
    exit()')       继续给子进程输入信息
    # 启动一个子进程,然后控制其输入和输出
    print(out.decode('utf-8'))
    print('parent')
    [root@oracle scripts]# python stu_subprocess.py 
    hello
    
    parent
    [root@oracle scripts]# cat sub_popen2.py 
    #!/usr/bin/python
    #coding=utf8
    
    import subprocess
     
    obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    obj.stdin.write(b'print("hello")
    ')         stdin.write和communicate两者交换使用
    obj.stdin.write(b'print("world")')
     
    out,err = obj.communicate()
    print(out)
    [root@oracle scripts]# python sub_popen2.py 
    b'hello
    world
    '
    call():
    subprocess.call()
    父进程等待子进程完成
    返回退出信息(returncode,相当于Linux exit code)
    [root@oracle scripts]# cat sub_call.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.call(['ls','-l'],shell=False)
    print(type(child))
    print('parent')
    [root@oracle scripts]# python sub_call.py 
    total 12
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 135 Aug 21 15:45 sub_call.py
    -rw-r--r-- 1 root root 136 Aug 21 15:41 sub_popen.py
    <class 'int'>                call函数返回的是int
    parent
    调用call函数可以明显看出子进程阻塞了主进程的运行,先运行子进程,最后才是主进程
    [root@oracle scripts]# cat sub_call.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.call(['ls','-l'],shell=False)
    print(type(child))
    print(child)                  ----->returncode
    print('parent')
    [root@oracle scripts]# python sub_call.py        
    total 12
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 148 Aug 21 15:53 sub_call.py
    -rw-r--r-- 1 root root 149 Aug 21 15:47 sub_popen.py
    <class 'int'>
    0
    parent
    subprocess.call(*popenargs, **kwargs):运行命令。该函数将一直等待到子进程运行结束,并返回进程的returncode。如果子进程不需要进行交互,就可以使用该函数来创建。
    call函数返回的是returncode,也就是int类型
    
    根据shell类型不同,可以更改传入call函数的args类型:
    [root@oracle scripts]# cat sub_call.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.call("ls -l",shell=True)       
    print(type(child))
    print(child)
    print('parent')
    shell=True参数会让subprocess.call接受字符串类型的变量作为命令,并调用shell去执行这个字符串,当shell=False是,subprocess.call只接受数组变量作为命令,并将数组的第一个元素作为命令,剩下的全部作为该命令的参数。
    [root@oracle scripts]# python sub_call.py 
    total 40
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 143 Aug 21 17:22 sub_call.py
    -rw-r--r-- 1 root root 143 Aug 21 16:33 sub_check_output.py
    -rw-r--r-- 1 root root 162 Aug 21 17:17 sub_getoutput.py
    -rw-r--r-- 1 root root 279 Aug 21 16:17 sub_popen.py
    -rw-r--r-- 1 root root 148 Aug 21 16:29 sub_run.py
    -rw-r--r-- 1 root root 257 Aug 21 16:53 test_subprocess1.py
    -rw-r--r-- 1 root root 340 Aug 21 16:52 test_subprocess2.py
    -rw-r--r-- 1 root root 332 Aug 21 17:03 test_subprocess3.py
    -rw-r--r-- 1 root root 183 Aug 21 16:44 test_subprocess.py
    <class 'int'>
    0
    parent
    所以当shell默认为False时,args传入的值必须是列表,而不能是str
    from subprocess import call  
    import shlex  
    cmd = "cat test.txt; rm test.txt"  
    call(cmd, shell=True)
    shell介绍:
    https://zhidao.baidu.com/question/651286079254739125.html
    
    3.5新增的run():
    class subprocess.CompletedProcess
    The return value from run(), representing a process that has finished.
    [root@oracle scripts]# cat sub_run.py 
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.run(['ls','-l'],shell=False)
    print(type(child))
    print(child)
    print('parent')
    [root@oracle scripts]# python sub_run.py 
    total 16
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 148 Aug 21 15:53 sub_call.py
    -rw-r--r-- 1 root root 149 Aug 21 15:47 sub_popen.py
    -rw-r--r-- 1 root root 147 Aug 21 15:56 sub_run.py
    <class 'subprocess.CompletedProcess'>
    CompletedProcess(args=['ls', '-l'], returncode=0)
    parent
    
    check_output():
    [root@oracle scripts]# cat sub_check_output.py
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.check_output(['ls','-l'],shell=False)
    print(type(child))
    print(child)
    print('parent')
    [root@oracle scripts]# python sub_check_output.py
    <class 'bytes'>
    b'total 20
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 148 Aug 21 15:53 sub_call.py
    -rw-r--r-- 1 root root 156 Aug 21 16:26 sub_check_output.py
    -rw-r--r-- 1 root root 279 Aug 21 16:17 sub_popen.py
    -rw-r--r-- 1 root root 147 Aug 21 15:56 sub_run.py
    '
    parent
     
    [root@oracle scripts]# cat sub_check_output.py
    #!/usr/bin/python
    #coding=utf8
    import subprocess
    child = subprocess.check_output(['ls','-l'],shell=False)
    print(type(child))
    print('parent')
    [root@oracle scripts]# python sub_check_output.py
    <class 'bytes'>
    parent
    并没有打印出子进程运行后的内容
    
    subprocess.getoutput(cmd),返回的是一个字符串
    Return output (stdout and stderr) of executing cmd in a shell.
    [root@oracle scripts]# python sub_getoutput.py 
    <class 'str'>
    stu_subprocess.py
    sub_call.py
    sub_check_output.py
    sub_getoutput.py
    sub_popen.py
    sub_run.py
    test_subprocess1.py
    test_subprocess2.py
    test_subprocess3.py
    test_subprocess.py
    [root@oracle scripts]# cat sub_getoutput.py 
    #!/usr/bin/python
    #coding=utf8
    
    import subprocess
    
    def TestGetOutput():
      outp = subprocess.getoutput(["ls" ,"-l"])      列表
      print(type(outp))
      print(outp)
    
    TestGetOutput()
    [root@oracle scripts]# cat sub_getoutput.py 
    #!/usr/bin/python
    #coding=utf8
    
    import subprocess
    
    def TestGetOutput():
      outp = subprocess.getoutput("ls -l")        字符串
      print(type(outp))
      print(outp)
    
    TestGetOutput()
    [root@oracle scripts]# python sub_getoutput.py 
    <class 'str'>
    total 40
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 148 Aug 21 15:53 sub_call.py
    -rw-r--r-- 1 root root 143 Aug 21 16:33 sub_check_output.py
    -rw-r--r-- 1 root root 162 Aug 21 17:17 sub_getoutput.py
    -rw-r--r-- 1 root root 279 Aug 21 16:17 sub_popen.py
    -rw-r--r-- 1 root root 148 Aug 21 16:29 sub_run.py
    -rw-r--r-- 1 root root 257 Aug 21 16:53 test_subprocess1.py
    -rw-r--r-- 1 root root 340 Aug 21 16:52 test_subprocess2.py
    -rw-r--r-- 1 root root 332 Aug 21 17:03 test_subprocess3.py
    -rw-r--r-- 1 root root 183 Aug 21 16:44 test_subprocess.py
    
    #接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果 
    >>> subprocess.getstatusoutput('ls -l')     
    (0, 'total 40
    -rw-r--r-- 1 root root 256 Aug 21 15:26 stu_subprocess.py
    -rw-r--r-- 1 root root 143 Aug 21 17:22 sub_call.py
    -rw-r--r-- 1 root root 143 Aug 21 16:33 sub_check_output.py
    -rw-r--r-- 1 root root 162 Aug 21 17:17 sub_getoutput.py
    -rw-r--r-- 1 root root 279 Aug 21 16:17 sub_popen.py
    -rw-r--r-- 1 root root 148 Aug 21 16:29 sub_run.py
    -rw-r--r-- 1 root root 257 Aug 21 16:53 test_subprocess1.py
    -rw-r--r-- 1 root root 340 Aug 21 16:52 test_subprocess2.py
    -rw-r--r-- 1 root root 332 Aug 21 17:03 test_subprocess3.py
    -rw-r--r-- 1 root root 183 Aug 21 16:44 test_subprocess.py')
    
     
  • 相关阅读:
    AJAX异步传输——以php文件传输为例
    js控制json生成菜单——自制菜单(一)
    vs2010中关于HTML控件与服务器控件分别和js函数混合使用的问题
    SQL数据库连接到服务器出错——无法连接到XXX
    PHP错误:Namespace declaration statement has to be the very first statement in the script
    【LeetCode】19. Remove Nth Node From End of List
    【LeetCode】14. Longest Common Prefix
    【LeetCode】38. Count and Say
    【LeetCode】242. Valid Anagram
    【LeetCode】387. First Unique Character in a String
  • 原文地址:https://www.cnblogs.com/jsonhc/p/7410224.html
Copyright © 2011-2022 走看看