>>> import subprocess >>> retcode = subprocess.call(["ls", "-l"]) #和shell中命令ls -a显示结果一样 >>> print retcode 0将程序名(ls)和所带的参数(-l)一起放在一个表中传递给subprocess.call()
>>> retcode = subprocess.call("ls -l",shell=True)在Windows下,不论shell的值如何,Popen调用CreateProcess()执行args指定的外部程序。如果args是一个序列,则先用list2cmdline()转化为字符串,但需要注意的是,并不是MS Windows下所有的程序都可以用list2cmdline来转化为命令行字符串。
>>> import subprocess >>> child = subprocess.Popen(['ping','-c','4','blog.linuxeye.com']) >>> print 'parent process'从运行结果中看到,父进程在开启子进程之后并没有等待child的完成,而是直接运行print。
>>> import subprocess >>> child = subprocess.Popen('ping -c4 blog.linuxeye.com',shell=True) >>> child.wait() >>> print 'parent process'从运行结果中看到,父进程在开启子进程之后并等待child的完成后,再运行print。
child.poll() # 检查子进程状态 child.kill() # 终止子进程 child.send_signal() # 向子进程发送信号 child.terminate() # 终止子进程 子进程的PID存储在child.pid
(5)子进程的文本流控制
子进程的标准输入、标准输出和标准错误如下属性分别表示:child.stdin child.stdout child.stderr可以在Popen()建立子进程的时候改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe),如下2个例子:
>>> import subprocess >>> child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE) >>> print child1.stdout.read(), #或者child1.communicate()
>>> import subprocess >>> child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE) >>> child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE) >>> out = child2.communicate()subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
def system_exec(args, timeout=2, shell=False, interval=0.01): ''' @args: command array ''' retval = 0 output = "success" end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout) try: # output = subprocess.check_output(args, shell=shell) # 没有指定标准输出和错误输出的管道,因此会打印到屏幕上; sub = subprocess.Popen(args, stdout=subprocess.PIPE, shell=shell, bufsize=4096) #subprocess.poll()方法:检查子进程是否结束了,如果结束了,设定并返回码,放在subprocess.returncode变量中 while sub.poll() is None: time.sleep(interval) if end_time <= datetime.datetime.now(): sub.terminate() return (-1, "Command Timeout") else: pass ## read all lines from stdout with sub.stdout as fd: output = fd.read() # read() or readlines() retval = sub.returncode output = output.strip() ## strip the last \n fd.close() except Exception as e: retval = -1 output = str(e) return retval, output