pyopen Python subprocess

shkex 模块最常见的用法就是其中的split 函数,split 函数提供了和shell 处理命令行参数时一致的分隔方式



代码示例:
shlex.split(“python -u a.py -a A -b B -o test”)
[‘python’, ‘-u’, ‘a.py’, ‘-a’, ‘A’, ‘-b’, ‘B’, ‘-o’, ‘test’]
在shell 中,对于选项和对应的值之间可以有多个空格,而shlex.split 保持了和sell 一致的处理方式

subprocess模块是干嘛的:



DESCRIPTION
This module allows you to spawn processes, connect to their
input/output/error pipes, and obtain their return codes.



即允许你去创建一个新的进程让其执行另外的程序,并与它进行通信,获取标准的输入、标准输出、标准错误以及返回码等。
注意:使用这个模块之前要先引入该模块。



Popen类



subprocess模块中定义了一个Popen类,通过它可以来创建进程,并与其进行复杂的交互。查看一下它的构造函数:
init(self, args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None, preexec_fn=None,
close_fds=False, shell=False, cwd=None, env=None,
universal_newlines=False, startupinfo=None,
creationflags=0)
主要参数说明:
args:args should be a string, or a sequence of program arguments.也就是说必须是一个字符串或者序列类型(如:字符串、list、元组),用于指定进程的可执行文件及其参数。如果是一个序列类型参数,则序列的第一个元素通常都必须是一个可执行文件的路径。当然也可以使用executeable参数来指定可执行文件的路径。



stdin,stdout,stderr:分别表示程序的标准输入、标准输出、标准错误。有效的值可以是PIPE,存在的文件描述符,存在的文件对象或None,如果为None需从父进程继承过来,stdout可以是PIPE,表示对子进程创建一个管道,stderr可以是STDOUT,表示标准错误数据应该从应用程序中捕获并作为标准输出流stdout的文件句柄。



shell:如果这个参数被设置为True,程序将通过shell来执行。
env:它描述的是子进程的环境变量。如果为None,子进程的环境变量将从父进程继承而来。



创建Popen类的实例对象
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
cmd:标准像子进程传入需要执行的shell命令,如:ls -al



subprocess.PIPE:在创建Popen对象时,subprocess.PIPE可以初始化为stdin, stdout或stderr的参数,表示与子进程通信的标准输入流,标准输出流以及标准错误。



subprocess.STDOUT:作为Popen对象的stderr的参数,表示将标准错误通过标准输出流输出。



Popen类拥有的方法及属性



1、Popen.pid
获取子进程的进程ID。



2、Popen.returncode



获取进程的返回码。如果进程未结束,将返回None。



3、communicate(input=None)



官方解释:



Interact with process: Send data to stdin. Read data from
stdout and stderr, until end-of-file is reached. Wait for
process to terminate. The optional input argument should be a
string to be sent to the child process, or None, if no data
should be sent to the child.



communicate() returns a tuple (stdout, stderr).



与子进程进行交互,像stdin发送数据,并从stdout和stderr读出数据存在一个tuple中并返回。
参数input应该是一个发送给子进程的字符串,如果未指定数据,将传入None。



4、poll()
检查子进程是否结束,并返回returncode属性。



5、wait()
Wait for child process to terminate. Returns returncode attribute.
等待子进程执行结束,并返回returncode属性,如果为0表示执行成功。



6、send_signal( sig)
Send a signal to the process
发送信号给子进程。



7、terminate()
Terminates the process
终止子进程。windows下将调用Windows API TerminateProcess()来结束子进程。



8、kill()
官方文档对这个函数的解释跟terminate()是一样的,表示杀死子进程。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import subprocess
class Shell(object) :
def runCmd(self, cmd) :
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
sout ,serr = res.communicate()
return res.returncode, sout, serr, res.pid

shell = Shell()
while 1 :
input = raw_input('>')
if input == 'exit' or input == 'bye' :
break
else :
result = shell.runCmd(input)
print "返回码:", result[0]
print "标准输出:", result[1]
print "标准错误:", result[2]



#!/usr/bin/expect -f
# sudo apt-get install expect
# ./ssh.exp user passwd server
set user [lrange $argv 0 0]
set pass [lrange $argv 1 1]
set server [lrange $argv 2 2]
set cmds [lrange $argv 3 $argc]



spawn ssh -o StrictHostKeyChecking=no $user@$server $cmds
match_max 100000
expect “?assword:
send – “$pass\r”
send – “\r”
interact



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/local/bin/python
#encoding=utf-8
import subprocess
import shlex
class Shell(object) :
def runCmd(self, cmd) :
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sout ,serr = res.communicate()
#print sout,serr
return res.returncode, sout, serr, res.pid
shell = Shell()
while 1 :
input = raw_input('>')
if input == 'exit' or input == 'bye' :
break
else :
ssh_args = ' %s %s %s %s %s \"%s\" ' % ("sshpass","-p","12345","ssh","user@192.123.11.12","ls -al ./")
print ssh_args
result = shell.runCmd(ssh_args)
#result = shell.runCmd(input)
print result
print "返回码docker:", result[0]
print "标准输出docker:", result[1]
print "标准错误docker:", result[2]
print "docker pid: ",result[3]
result = shell.runCmd(input)
print "返回码:", result[0]
print "标准输出:", result[1]
print "标准错误:", result[2]
result2 = shell.runCmd('exit')
print result2



Category linux