Python运行外部命令并在屏幕上或者变量中获取输出

时间:2020-01-09 10:43:07  来源:igfitidea点击:

如何运行Linux或者Unix外部程序。
例如,如何用我的python脚本调用一个名为/bin/date的外部程序,并将输出显示在屏幕上或者存储在变量中。
如何使用Python脚本显示/bin/date程序的此类输出和退出状态(返回代码)?

您需要使用subprocessPython模块,该模块允许您生成新进程,连接到它们的输入/输出/错误管道,并获取它们的返回代码。
另一个选择是使用Python提供的操作系统接口,例如:os.system os.spawn * os.popen *

在python中调用外部程序,并使用subprocess检索输出/返回代码

基本语法为:

import subprocess
subprocess.call("command-name-here")
subprocess.call(["/path/to/command", "arg1", "-arg2"])

运行ping命令将ICMP ECHO_REQUEST数据包发送到www.theitroad.local:

#!/usr/bin/python
import subprocess
subprocess.call(["ping", "-c 2", "www.theitroad.local"])

输出示例:

PING www.theitroad.local (75.126.153.206): 56 data bytes
64 bytes from 75.126.153.206: icmp_seq=0 ttl=53 time=250.416 ms
64 bytes from 75.126.153.206: icmp_seq=1 ttl=53 time=264.461 ms
 
--- www.theitroad.local ping statistics --
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 250.416/257.438/264.461/7.023 ms

示例:运行外部日期命令并在屏幕上显示输出

在此示例中,运行标准的Unix date命令并在屏幕上显示输出:

#!/usr/bin/python
## get subprocess module 
import subprocess
 
## call date command ##
p = subprocess.Popen("date", stdout=subprocess.PIPE, shell=True)
 
## Talk with date command i.e. read data from stdout and stderr. Store this info in tuple ##
## 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.
(output, err) = p.communicate()
 
## Wait for date to terminate. Get return returncode ##
p_status = p.wait()
print "Command output : ", output
print "Command exit status/return code : ", p_status

输出示例:

Command output :  Mon Dec 30 23:50:43 IST 2013

Command exit status/return code :  0

如何从屏幕上的命令获得实时输出?

p.communicate()有一些问题:

  • 读取的数据缓存在内存中,因此,如果数据大小很大或者没有限制,请不要使用此方法。
  • 它将阻塞下一条语句,直到外部命令完成为止,即您将无法从命令获得实时输出。

以下程序将运行netstat unix命令并立即在屏幕上开始显示输出:

#!/usr/bin/python
import subprocess, sys
## command to run - tcp only ##
cmd = "/usr/sbin/netstat -p tcp -f inet"
 
## run it ##
p = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
 
## But do not wait till netstat finish, start displaying output immediately ##
while True:
    out = p.stderr.read(1)
    if out == '' and p.poll() != None:
        break
    if out != '':
        sys.stdout.write(out)
        sys.stdout.flush()

输出示例:

Active Internet connections
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)    
tcp4       0      0  desktop01.52712        proxy1.theitroadu.http  ESTABLISHED
tcp4       0      0  desktop01.52710        proxy1.theitroadu.http  ESTABLISHED
tcp4       0      0  desktop01.52701        proxy1.theitroadu.http  ESTABLISHED
tcp4       0      0  desktop01.52277        proxy1.theitroadu.http  ESTABLISHED
tcp4       0      0  desktop01.52021        maa03s17-in-f21..https ESTABLISHED
tcp4     146      0  desktop01.49548        maa03s04-in-f0.1.https CLOSE_WAIT 
tcp4       0      0  desktop01.49292        ni-in-f125.1e100.jabbe ESTABLISHED
tcp4       0      0  desktop01.49154        10.172.232.154.5223    ESTABLISHED