python调用外部程序&subprocess模块的详细使用说明


注:本文只介绍 python3.6+

以jupyter 文件阅读本文

Windows 调用外部程序

可以使用 win32process 模块中的函数。如果想进一步控制进程,则可以使用 ctype 模块,直接调用 kernel32.dll 中的函数

  1. 使用 os.system 函数运行其他程序
  2. 使用 ShellExecute 函数运行其他程序
  3. 使用 CreateProcess 函数运行其他程序
  4. 使用 ctypes 调用 kernel32.dll 中的函数
import os
import win32api
import win32process
import win32event

os.system(command)

说明:

  • 等待执行
  • 正常结束返回 0

或者 os.popen(command), 详细讲解见下文

用法举例

import os

#  打开记事本程序
os.system('notepad')
# 关闭记事本后的返回值  0
0
# 向记事本传递参数,打开python.txt文件
os.system('notepad python.txt')
0

win32api.ShellExecute(hwnd, op , file , params , dir , bShow )

参数:

  • hwnd:父窗口的句柄,如果没有父窗口,则为 0。
  • op:要进行的操作,为“open”、“print”或者为空。
  • file:要运行的程序,或者打开的脚本。
  • params:要向程序传递的参数,如果打开的为文件,则为空。
  • dir:程序初始化的目录。
  • bShow:是否显示窗口。

说明:

  • 不用等待
  • 相当于在资源管理器中双击文件图标一样,系统会打开相应的应用程序执行操作

用法举例

import win32api

打开记事本程序,在后台运行,即显示记事本程序的窗口

win32api.ShellExecute(0, 'open', 'notepad', '', '', 0)
42

打开记事本程序,在前台运行

win32api.ShellExecute(0, 'open', 'notepad.exe', '', '', 1)
42

向记事本传递参数,打开 python.txt

win32api.ShellExecute(0, 'open', 'notepad.exe', 'python.txt', '', 1)
42

在默认浏览器中打开http://www.python.org网站

win32api.ShellExecute(0, 'open', 'http://www.python.org', '', '', 1)
42

在默认的媒体播放器中播放 E:\song.wma

win32api.ShellExecute(0, 'open', 'E:\\song.wma', '', '', 1)

运行位于 E:\book\code 目录中的 MessageBox.py 脚本

win32api.ShellExecute(0, 'open', 'E:\\book\\code\\MessageBox.py', '', '', 1)

win32process.CreateProcess 创建进程

形式:

CreateProcess(appName, commandLine , processAttributes , threadAttributes , bInheritHandles ,dwCreationFlags , newEnvironment , currentDirectory , startupinfo )

参数:

  • appName:可执行的文件名。
  • commandLine:命令行参数。
  • processAttributes:进程安全属性,如果为 None,则为默认的安全属性。
  • threadAttributes:线程安全属性,如果为 None,则为默认的安全属性。
  • bInheritHandles:继承标志。
  • dwCreationFlags:创建标志。
  • newEnvironment:创建进程的环境变量。
  • currentDirectory:进程的当前目录。
  • startupinfo :创建进程的属性。

说明:

  • 不用等待
  • 可通过句柄控制终止、等待
import win32process

handle = win32process.CreateProcess('c:\\windows\\notepad.exe', '', None, None,
                                    0, win32process.CREATE_NO_WINDOW, None,
                                    None, win32process.STARTUPINFO())

终止控制 win32process.TerminateProcess

参数:

  • handle:要操作的进程句柄。
  • exitCode:进程退出代码。
handle = win32process.CreateProcess('c:\\windows\\notepad.exe', '', None, None,
                                    0, win32process.CREATE_NO_WINDOW, None,
                                    None, win32process.STARTUPINFO())
win32process.TerminateProcess(handle[0], 0)

等待控制 win32event.WaitForSingleObject

参数:

  • handle:要操作的进程句柄。
  • milliseconds:等待的时间,如果为 1,则一直等待。

返回值 0

handle = win32process.CreateProcess('c:\\windows\\notepad.exe', '', None, None,
                                    0, win32process.CREATE_NO_WINDOW, None,
                                    None, win32process.STARTUPINFO())
# 等待进程结束, 等待时间 默认 -1(永远)
win32event.WaitForSingleObject(handle[0], -1)
# 进程结束的返回值
0

使用 ctypes 调用 kernel32.dll 中的函数

使用 ctypes 模块可以使 Python 调用由 C 语言编写的动态链接库,并向其传递参数。
ctypes 定义了 C 语言中的基本数据类型,并且可以实现 C 语言中的结构体和联合体。ctypes 可以工作在 Windows、Windows CE、Mac OS X、Linux、Solaris、FreeBSD、OpenBSD 等平台上,基本上实现了跨平台

在 Windows 下直接调用 user32.dll 中的 MessageBoxA 函数:

from ctypes import *

user32 = windll.LoadLibrary('user32.dll')  # 加载动态链接库
# 调用MessageBoxA函数.
user32.MessageBoxA(0, b'Ctypes is cool!', 'Ctypes', 0)
1

OS 模块

os.system(command)

  • 等待执行
  • 有返回值
  • 输出流不可捕获

官方文档解释

翻译如下:

在子 shell 中执行命令(参数:字符串)。这是通过调用标准 C 函数系统()来实现的,并且具有相同的限制。

改变 sys.stdin (,etc) 不会在执行此次命令中生效。如果 command 生成任何输出,它将被发送到解释器标准输出流。(即,所有输出信息都会显示到命令行中)

在 Unix 上,返回值是以 wait()指定的格式编码的进程的退出状态。请注意,POSIX 未指定 C 语言 system()函数的返回值的含义,因此 Python 函数的返回值取决于系统。

在 Windows 上,返回值是运行命令后系统 shell 返回的值。shell 由 Windows 环境变量 COMSPEC 给出:它通常是 cmd.exe,它返回命令运行的退出状态;在使用非本机 shell 的系统上,请参阅 shell 文档。

subprocess 模块提供了更强大的工具来生成新进程并检查其结果;使用该模块比使用 os.system 更可取。

用法举例

import os
#  打开记事本程序
os.system('notepad')
# 关闭记事本后的返回值  0
0

os.popen

  • 不用等待,读取结果 stdout 需要等待
  • 返回管道(IO 包装对象,类似文件对象),可 read()、readline() 等

本质是使用 subprocess.Popen 方法实现

同样的,官方推荐使用 subprocess 代替此方法。

底层实现如下:

Signature: os.popen(cmd, mode='r', buffering=-1)
Docstring: <no docstring>
Source:
def popen(cmd, mode="r", buffering=-1):
    if not isinstance(cmd, str):
        raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
    if mode not in ("r", "w"):
        raise ValueError("invalid mode %r" % mode)
    if buffering == 0 or buffering is None:
        raise ValueError("popen() does not support unbuffered streams")
    import subprocess, io
    if mode == "r":
        proc = subprocess.Popen(cmd,
                                shell=True,
                                stdout=subprocess.PIPE,
                                bufsize=buffering)
        return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
    else:
        proc = subprocess.Popen(cmd,
                                shell=True,
                                stdin=subprocess.PIPE,
                                bufsize=buffering)
        return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
File:      d:\softinstall\anacoda3\lib\os.py

import os
os.popen??

用法举例

import os

p = os.popen('ping www.baidu.com')
p
<os._wrap_close at 0x2b6682f4080>

等待进程执行完毕后才可读出执行结果(阻塞)

print(p.read())
正在 Ping www.baidu.com [180.101.49.11] 具有 32 字节的数据:
来自 180.101.49.11 的回复: 字节=32 时间=119ms TTL=53
来自 180.101.49.11 的回复: 字节=32 时间=343ms TTL=53
来自 180.101.49.11 的回复: 字节=32 时间=58ms TTL=53
来自 180.101.49.11 的回复: 字节=32 时间=187ms TTL=53

180.101.49.11 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 58ms,最长 = 343ms,平均 = 176ms
# 输入一个错误命令
p = os.popen('notepada')
p.read()
# 没有错误信息, 原因见上面实现代码
''

说明:

以上两个方法的 subprocess 替代用法,见官方连接:

Replacing Older Functions with the subprocess Module


subprocess 模块

官方文档

Popen–最基本的类

说明:创建一个新的进程执行命令,返回一个实例,进行后续操作

本质:

在 POSIX,此类使用类似于 os.execvp() 的行为来执行子程序。
在 Windows,此类使用了 Windows CreateProcess() 函数。

  • 非阻塞,可以 wait()等待.
  • 支持多种参数和模式,方便控制和进程交互
  • 可捕获运行输出和返回状态码

Popen 原型是:

Popen(args, bufsize=-1, executable=None,
                 stdin=None, stdout=None, stderr=None,
                 preexec_fn=None, close_fds=True,
                 shell=False, cwd=None, env=None, universal_newlines=None,
                 startupinfo=None, creationflags=0,
                 restore_signals=True, start_new_session=False,
                 pass_fds=(), *, encoding=None, errors=None, text=None)

参数:

  • args: 一个字符串命令,或者参数序列(最终还是转为一个字符串)。提供一个参数序列通常更好,它可以更小心地使用参数中的转义字符以及引用(例如允许文件名中的空格)。如果传递一个简单的字符串,则 shell 参数(Linux 下)必须为 True,或者用 executable 参数指定运行该命令的程序。

参数既可以是 string,也可以是 list。

对于参数是字符串,需要指定 shell=True

subprocess.Popen([“cat”,”test.txt”])
subprocess.Popen(“cat test.txt”, shell=True)

linux 下如果传入一个序列,则该序列的第一个元素默认当作执行后续参数的程序,比如:

cmd = [“ssh”, 'root@192.168.1.2"]

则用 ssh 去执行后续参数


  • bufsize:当创建 stdin/stdout/stderr 管道文件时,为 open() 方法提供 buffering 参数 z

  • executable:用于指定可执行程序。一般情况下我们通过 args 参数来设置所要运行的 shell 程序。如果将参数 shell 设为 True,executable 将指定程序使用的 shell。在 windows 平台下,默认的 shell 由 COMSPEC 环境变量来指定。(比如 cmd.exe)

  • stdin, stdout, stderr分别表示程序的标准输入、输出、错误句柄。他们可以是:

    • PIPE
    • 文件描述符
    • 文件对象,
    • None,表示从父进程继承。
    • stderr 还可以设置为subprocess.STDOUT
  • preexec_fn:钩子函数,只在 Unix 平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用

  • close_fds:控制关闭或者继承文件描述符。在 windows 平台下,如果 close_fds 被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。我们不能将 close_fds 设置为 True 同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。

  • shell:如果设为True,unix 下相当于args前面添加了 “/bin/sh” “-c” ,Windows 下相当于添加了 “cmd.exe /c”

  • cwd:用于设置子进程的当前目录

  • env:字典类型,用于指定子进程的环境变量。如果 env = None,子进程的环境变量将从父进程中继承

  • universal_newlines:控制统一换行符。不同操作系统下,文本的换行符是不一样的。如:windows 下用’\r\n’表示换,而 Linux 下用 ‘\n’。如果将此参数设置为 True,Python 统一把换行符处理为’\n’。

  • startupinfo: 只在 windows 下用效,传递给底层 CreateProcess()的结构体,用 于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

  • creationflags: 只在 windows 下用效, 传递给CREATE_NEW_CONSOLE创建自己的控制台窗口

  • restore_signals:POSIX only

  • start_new_session:POSIX only

  • pass_fds:POSIX only

  • encoding and errors: 文件对象stdin、stdout、和stderr的解码方式,以及解码的处理方式(比如:ignore、strict,参考encode())

  • text:如果设为True,用给定的encoding参数解码 stdin, stdout and stderr,如果encoding未指定,则使用系统默认编码。

基本用法

此例是在 windows 上执行一条错误命令 notepad(打开记事本)。

注意:
如果不设置 stderr=subprocess.PIPE,则获取不到错误信息

communicate() 方法见下文。

import subprocess

p = subprocess.Popen('notepada',
                     shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE)

# 注意解码Windows上默认 gbk,换行符为 \r\n
stdoutdata, stderrdata = p.communicate()
stdoutdata.decode('gbk')
''
stderrdata.decode('gbk')
"'notepada' 不是内部或外部命令,也不是可运行的程序\r\n或批处理文件。\r\n"

指定编码方式 或者 统一换行符参数都会将输出流编码

p = subprocess.Popen('notepada',
                     shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE, encoding='gbk')
# p = subprocess.Popen('notepada',
#                      shell=True,
#                      stdout=subprocess.PIPE,
#                      stderr=subprocess.PIPE, universal_newlines=True)

stdoutdata, stderrdata = p.communicate()
stdoutdata, stderrdata
('', "'notepada' 不是内部或外部命令,也不是可运行的程序\n或批处理文件。\n")

Popen 的常用方法

Popen.poll()

用于检查子进程是否已经结束。

  • 不会等待进程
  • 进程未结束返回None
  • 进程结束返回 returncode。

p.poll()


Popen.wait(timeout=None)

在规定时间内等待进程结束,设置 timeout=None,则一直等待直到结束

返回:returncode

p.wait()


Popen.communicate(input=None)

功能:

  • 等待进程结束

  • 与子进程进行交互。向stdin发送数据并关闭它。可选参数input指定发送到子进程的数据,注意 Popen对象的**encoding或者text参数**决定传入字符串还是字节流。

  • stdoutstderr中读取数据, 并关闭。

如果没有数据发送到子进程(stdin),则返回一个元组:(stdoutdata, stderrdata)。

注意:

如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如果希望从stdoutstderr获取数据,必须将stdoutstderr设置为PIPE

警告:

使用 communicate()而不是.stdin.write,.stdout.read 或.stderr.read 来避免由于任何其他 OS 管道缓冲区填满和阻止子进程而导致的死锁


Popen.send_signal(sig)

向进程发送信号(方法内部自行检查进程是否已经终止,已经终止是不会响应信号的)

import signal

两种情况的参数:

Windows 上:

  • 终止:signal.SIGTERM
  • Ctrl + C:signal.CTRL_C_EVENT
  • Ctrl + Break:signal.CTRL_BREAK_EVENT

Linux 上:

  • 终止:signal.SIGTERM 或者 signal.SIGKILL

例如:

import signal
p.send_signal(signal.SIGTERM)

Popen.terminate()

停止子进程。在 Posix 操作系统上,此方法发送 SIGTERM。在 Windows,调用 Win32 API 函数 TerminateProcess() 来停止子进程


Popen.kill()

在 Posix 操作系统上,此函数给子进程发送 SIGKILL 信号。在 Windows 上, kill()terminate() 的别名。


Popen 的属性

Popen.stdin

  • 如果 stdin 参数为 PIPE,此属性是一个类似 open() 返回的可写的流对象。

  • 如果 encodingerrors 参数被指定或者 universal_newlines 参数为 True,则此流是一个字符串,否则是字节流。

  • 如果 stdin 参数非 PIPE, 此属性为 None


Popen.stdout

  • 如果 stdin 参数为 PIPE,此属性是一个类似 open() 返回的可读的流对象。

  • 如果 encodingerrors 参数被指定或者 universal_newlines 参数为 True,则此流是一个字符串,否则是字节流。

  • 如果 stdin 参数非 PIPE, 此属性为 None


Popen.stderr

  • 如果 stdin 参数为 PIPE,此属性是一个类似 open() 返回的可读的流对象。

  • 如果 stdin 参数为subprocess.STDOUT ,则错误输出到 stdout。

  • 如果 encodingerrors 参数被指定或者 universal_newlines 参数为 True,则此流是一个字符串,否则是字节流。

  • 如果 stdin 参数非 PIPE, 此属性为 None


Popen.pid

获取子进程的进程 ID。


Popen.returncode

获取进程的返回值。如果进程还没有结束,返回 None。

常量

subprocess.PIPE

在创建Popen对象时,subprocess.PIPE可以初始化stdin, stdoutstderr参数,表示与子进程通信的标准流。如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为subprocess.PIPE

subprocess.STDOUT

创建 Popen 对象时,用于初始化 stderr 参数,表示将错误通过标准输出流输出。

subprocess.STD_INPUT_HANDLE

标准输入设备,初始化时,是从 console 控制台输入

subprocess.STD_OUTPUT_HANDLE

标准输出设备,初始化时,是活动 console 屏幕缓冲区

subprocess.STD_ERROR_HANDLE

标准错误输出设备,初始化时,同样是 console 屏幕缓冲区。

subprocess.SW_HIDE

隐藏窗口。另一个窗口将被激活

subprocess.CREATE_NEW_CONSOLE

新进程有一个新的控制台,而不是继承其父控制台(默认)。当使用 shell = True 创建 Popen 时,始终设置此标志。

基于 Popen 的其他方法

subprocess.call(*popenargs, timeout=None, **kwargs)

说明:
仅能执行命令和获取执行的返回码,和超时控制,没有其他功能。不能捕获输出流。

  • 使用参数运行命令
  • 等待完成
  • 返回 returncode 属性。
  • 超时触发TimeoutExpired 异常

参数:

同Popen构造函数
timeout:秒,用于等待完成,超时强制退出,释放所有资源

本质:

使用上下文管理器(with 语句):调用Popen(),以及Popen.wait(timeout)等待完成.

警告:

当输出数据较大时会发生死锁,用communicate()来避免。

示例:

retcode = subprocess.call(["ls", "-l"], shell=True)
retcode
1

subprocess.check_call(*popenargs, **kwargs)

说明:
在上面的 call()方法上加了 检查功能

  • 等待完成
  • 执行无误返回 0,否则引发CalledProcessError

参数:

同subprocess.call()

本质:

调用上面的call() 方法并在结束后检查 returncode是否为0.

警告:

当输出数据较大时会发生死锁,用communicate()来避免。
subprocess.check_call('calc')
0
subprocess.check_call(["ls", "-l"], shell=True)
---------------------------------------------------------------------------

CalledProcessError                        Traceback (most recent call last)

<ipython-input-25-e737dd244224> in <module>
----> 1 subprocess.check_call(["ls", "-l"], shell=True)


D:\SoftInstall\Anacoda3\lib\subprocess.py in check_call(*popenargs, **kwargs)
    345         if cmd is None:
    346             cmd = popenargs[0]
--> 347         raise CalledProcessError(retcode, cmd)
    348     return 0
    349


CalledProcessError: Command '['ls', '-l']' returned non-zero exit status 1.

CompletedProcess 类

(下面两个方法要用到)

run()方法的返回值

属性:

  • args:进程执行的命令,str 或者 list

  • returncode:结束返回值

  • stdout:标准输出

  • stderr:标准错误

方法:

  • check_returncode(): 检查 returncode 退出码,如果不是 0,引发 CalledProcessError 异常。

subprocess.run(*popenargs, input=None, capture_output=False, timeout=None, check=False, **kwargs):

说明:
可从返回的 CompletedProcess 的实例中获取 returncode、stdout、stderr 属性

  • 等待结束,或者超时异常
  • 超时控制
  • 结果检查
  • 进程安全,结束、异常终止都释放所占用资源
  • 在不超时,不检查 returncode,或者 returncode 为 0 的情况下返回 CompletedProcess 实例,否则直接异常退出

参数

  • Popen的参数通用

  • input:向进程通信传入的数据,bytes 或者 str。如果不为 None,则不能再传入 stdin参数

  • capture_output:如果设置为True,就不能再传入stdoutstderr参数,否则报错

  • timeout:限制执行时间,超时引发TimeoutExpired异常。默认为一直等待到执行结束

  • check :是否检查 returncode,如果不为 0,引发CalledProcessError异常 (可以先不检查,在返回的 CompletedProcess 实例中调用 check_returncode 方法再检查)

本质:

使用Popen的with语句,和communicate()方法等待结束,并加入了超时控制和返回码检查,捕获输出更加简单,是对Popen用法的封装,功能较全。

subprocess.check_output(*popenargs, timeout=None, **kwargs)

说明:执行命令,当命令执行成功(returncode=0)且未超时时,只返回 stdout 输出。

  • 与上述 run 类似
  • 运行失败引发CalledProcessError异常
  • 运行成功直接返回 stdout

参数:

  • 与 run() 通用
  • 不允许设置stdout参数

本质:

subprocess.run(…).stdout

疑问

如下:

查看 java 版本命令返回码为 0 ,但是输出到了标准错误流中,求告知。

subprocess.check_output(['java', '-version'])
b''
a = subprocess.run(['java', '-version'], capture_output=True, universal_newlines=True)
print(a.stderr)
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) Client VM (build 25.202-b08, mixed mode)
a = subprocess.Popen(['java', '-version'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
a.communicate()
('',
 'java version "1.8.0_202"\nJava(TM) SE Runtime Environment (build 1.8.0_202-b08)\nJava HotSpot(TM) Client VM (build 25.202-b08, mixed mode)\n')

subprocess.getstatusoutput(cmd)

说明:执行命令,成功后(returncode=0)返回一个元组(返回码,所有输出信息

参数:

  • cmd:执行的命令

本质:

调用 check_out()方法,并设置参数shell=True, text=True, stderr=STDOUT
即将 stderr 重定向到标准输出,得到的是所有输出信息

得到的输出信息较完整,且调用方便,建议使用

subprocess.getstatusoutput(['java', '-version'])
(0,
 'java version "1.8.0_202"\nJava(TM) SE Runtime Environment (build 1.8.0_202-b08)\nJava HotSpot(TM) Client VM (build 25.202-b08, mixed mode)')

subprocess.getoutput(cmd)

本质:调用subprocess.getstatusoutput,只取输出

getstatusoutput(cmd)[1]

subprocess.getoutput(['python', '-V'])
'Python 3.7.3'

使用举例以及注意事项

  • 使用 communicate 等待完成并获取输出,而不用其他的等待方法,避免发生系统 IO 阻塞(output 数据太多)
  • 参数 shell=True 在所执行的命令从 input() 输入的时候可能遭受 shell 注入攻击
  • 获取输出要与系统默认编码一致

如果超时到期,子进程不会被杀死,所以为了正确清理一个行为良好的应用程序应该杀死子进程并完成通讯

proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

在 POSIX 上建议 cmd 命令传入一个序列,而不是字符串,尤其是在复杂的情形下。

可以用 shellx.split(),方法将字符串安全正确的转换为一个列表序列:

>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!

在 windows 上序列会先转为字符串再执行

修改linux账户密码(向进程输入,注意使用回车\n)

subprocess.run('sudo passwd root', input=b'123\n123', shell =True)
输入新的 UNIX 密码:重新输入新的 UNIX 密码:passwd:已成功更新密码

执行结果保存在文件

cmd = 'ping www.baidu.com'
fhandle = open("aa.txt", "w")
pipe = subprocess.Popen(cmd, shell=True, stdout=fhandle)
fhandle.close()

执行结果使用管道输出

output = subprocess.Popen(["python", "-V"], stdout=subprocess.PIPE).communicate()[0]
output
b'Python 3.7.3\r\n'
pipe = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, encoding='gbk').stdout
print(pipe.read())
正在 Ping www.a.shifen.com [180.101.49.11] 具有 32 字节的数据:
来自 180.101.49.11 的回复: 字节=32 时间=97ms TTL=53
来自 180.101.49.11 的回复: 字节=32 时间=116ms TTL=53
来自 180.101.49.11 的回复: 字节=32 时间=145ms TTL=53
来自 180.101.49.11 的回复: 字节=32 时间=261ms TTL=53

180.101.49.11 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 97ms,最长 = 261ms,平均 = 154ms

代替 shell 管道符

查看 python 进程

ps -ef |grep python
p1 = subprocess.Popen(["ps", "-ef"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "hda"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

选择执行程序

在 windows 上使用 Git 的执行 shell 命令

exe_path = r'D:\SoftInstall\Git\git-cmd.exe'

p = subprocess.Popen('ifconfig',
                     executable=exe_path,
                     shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE,
                     universal_newlines=True)

p.communicate()
# 好像没有什么卵用
('\nD:\\OneDrive - business\\jupyter notebook\\Modules-Learn>', '')

传入环境变量

subprocess.Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值