Python常用模块-subprocess系统交互

Python常用模块-subprocess系统交互

http://www.cnblogs.com/alex3714/articles/5161349.html

https://www.cnblogs.com/iznogoud/articles/5607931.html

 

 

运行python的时候,我们都是在创建并运行一个进程。像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。
  subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。

标准例子

import subprocess
subprocess.run("ls ")
subprocess.run("ls -l")
subprocess.run("ls -l",shell=True)

>>> import subprocess
>>> subprocess.run("ls -l")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/python3.6.0/lib/python3.6/subprocess.py", line 403, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/local/python3.6.0/lib/python3.6/subprocess.py", line 707, in __init__
    restore_signals, start_new_session)
  File "/usr/local/python3.6.0/lib/python3.6/subprocess.py", line 1326, in _execute_child
    raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'ls -l'
>>> subprocess.run("ls -l",shell=True)
total 32
-rw-rw-r-- 1 admin admin   21 Jan 18 13:52 a.pw
drwxr-xr-x 7 admin admin 4096 Jul 10 00:21 data_bak
lrwxrwxrwx 1 admin admin   21 Jan 19 09:48 falcon -> /data/workdir/falcon/
-rwxr-xr-x 1 admin admin  167 Jan 18 13:52 iplist
lrwxrwxrwx 1 admin admin   19 Jun 27 10:03 jira -> /data/workdir/jira/
-rwxrwxrwx 1 admin admin  119 Jan 18 13:52 kill.sh
-rw-rw-r-- 1 admin admin 1011 Jan 18 13:52 list
lrwxrwxrwx 1 admin admin   22 Nov 10  2015 scripts -> /data/workdir/scripts/
-rw------- 1 admin admin    0 Jan 17 15:14 sent
lrwxrwxrwx 1 admin admin   19 Jan 18 10:29 soft -> /data/workdir/soft/
-rwxr-xr-x 1 admin admin   23 Jan 18 13:52 tianlala.sh
lrwxrwxrwx 1 admin admin   29 Jan 18 10:29 tomcat_jenkins -> /data/workdir/tomcat_jenkins/
drwxrwxr-x 4 admin admin 4096 Jun 13 16:31 wangxu
lrwxrwxrwx 1 admin admin   24 Nov  9  2015 webserver -> /data/workdir/webserver/
-rwxr-xr-x 1 admin admin   17 Jan 18 13:52 yuanzheng
CompletedProcess(args='ls -l', returncode=0)
>>>

 

调用subprocess.run(...)是推荐的常用方法,在大多数情况下能满足需求,但如果你可能需要进行一些复杂的与系统的交互的话,你还可以用subprocess.Popen(),语法如下:

import subprocess
ret = subprocess.Popen("du -sh",shell=True,stdout=subprocess.PIPE)
print(ret.stdout.read())

 

常用函数

https://www.cnblogs.com/sunshine-1/p/7290468.html

 

函数

描述

subprocess.run()

Python 3.5中新增的函数。执行指定的命令,等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。

subprocess.call()

执行指定的命令,返回命令执行状态,其功能类似于os.system(cmd)。

subprocess.check_call()

Python 2.5中新增的函数。 执行指定的命令,如果执行成功则返回状态码,否则抛出异常。其功能等价于subprocess.run(..., check=True)。

subprocess.check_output()

Python 2.7中新增的的函数。执行指定的命令,如果执行状态码为0则返回命令执行结果,否则抛出异常。

subprocess.getoutput(cmd)

接收字符串格式的命令,执行命令并返回执行结果,其功能类似于os.popen(cmd).read()和commands.getoutput(cmd)。

subprocess.getstatusoutput(cmd)

执行cmd命令,返回一个元组(命令执行状态, 命令执行结果输出),其功能类似于commands.getstatusoutput()。

说明:

  1. 在Python 3.5之后的版本中,官方文档中提倡通过subprocess.run()函数替代其他函数来使用subproccess模块的功能;
  2. 在Python 3.5之前的版本中,我们可以通过subprocess.call(),subprocess.getoutput()等上面列出的其他函数来使用subprocess模块的功能;
  3. subprocess.run()、subprocess.call()、subprocess.check_call()和subprocess.check_output()都是通过对subprocess.Popen的封装来实现的高级函数,因此如果我们需要更复杂功能时,可以通过subprocess.Popen来完成。
  4. subprocess.getoutput()和subprocess.getstatusoutput()函数是来自Python 2.x的commands模块的两个遗留函数。它们隐式的调用系统shell,并且不保证其他函数所具有的安全性和异常处理的一致性。另外,它们从Python 3.3.4开始才支持Windows平台。

 

可用参数

    • 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()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

终端输入的命令分为两种:

  • 输入即可得到输出,如:ifconfig
  • 输入进行某环境,依赖再输入,如:python

 

PIPI管道样例

import subprocess
 
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True)
# universal_newlines=True),否则会报TypeError: a bytes-like object is required, not 'str‘错误
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)

 

>>> import subprocess

>>> 

... obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True)

>>> obj.stdin.write("print('1')\n")

11

>>> obj.stdin.write("print('2')\n")

11

>>> obj.stdin.write("print('3')\n")

11

>>> obj.stdin.write("print('4')\n")

11

>>> out_error_list = obj.communicate(timeout=10)

>>> print(out_error_list)

('1\n2\n3\n4\n', '')

>>>  

import subprocess
m = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
m.stdin.write("print('hello')\n")
m.stdin.write("print('hello word')")
m.stdin.close()
m_out = m.stdout.read()
m.stdout.close()
m_error = m.stderr.read()
m.stderr.close()
print(m_out)
print(m_error)

 

>>> m = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

>>> m.stdin.write("print('hello')\n")

15

>>> m.stdin.write("print('hello word')")

19

>>> m.stdin.close()

>>> m_out = m.stdout.read()

>>> m.stdout.close()

>>> m_error = m.stderr.read()

>>> m.stderr.close()

>>> print(m_out)

hello

hello word

 

>>> print(m_error)

 

>>> 

 

subprocess实现sudo 自动输入密码

import subprocess
 
def mypass():
    mypass = '' #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())

 

>>> import subprocess

>>> 

... def mypass():

...     mypass = '' #or get the password from anywhere

...     return mypass

... 

... echo = subprocess.Popen(['echo',mypass()],stdout=subprocess.PIPE,

  File "<stdin>", line 6

    echo = subprocess.Popen(['echo',mypass()],stdout=subprocess.PIPE,

       ^

SyntaxError: invalid syntax

>>>                         )

  File "<stdin>", line 1

    )

    ^

IndentationError: unexpected indent

>>> 

... 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())

Password ok

 Iptables Chains b'Chain INPUT (policy ACCEPT)\ntarget     prot opt source               destination         \n\nChain FORWARD (policy ACCEPT)\ntarget     prot opt source               destination         \n\nChain OUTPUT (policy ACCEPT)\ntarget     prot opt source               destination         \n'

>>> 

 

posted on 2018-07-16 10:58  光阴8023  阅读(1226)  评论(1编辑  收藏  举报