Python运维-文本处理、系统和文件信息监控、外部命令

本节主要目录如下:

一、文本处理

1.1、Python编码解码

1.2、文件操作

1.3、读写配置文件

1.4、解析XML文件

二、系统信息监控

2.1、监控CPU信息

2.2、监控内存信息

2.3、监控磁盘信息

2.4、监控网络信息

2.5、获取进程信息

2.6、实例:常见的实用方法

三、文件系统监控

3.1、实例

四、执行外部命令subprocess

4.1、subprocess.run()方法*

4.2、Popen类

4.3、其他方法


一、文本处理

日常运维工作都离不开文本,如日志分析、编码转换、ETL加工等。

1.1、Python编码解码

  • 计算机只处理二进制数据,如果要处理文本,就需要将文本转换为二进制数据,再由计算机进行处理
  • 文本转换为二进制数据就是编码,将二进制数据转换为文本就是解码
  • 编码和解码要按一定的规则进行,这个规则就是字符集

常见的中文编码

  • GB2312GB2312-80是中国国家标准简体中文字符集,共收录6763个汉字,同时收录了包括拉丁字母、希腊字母。日文平假名字母、俄语西里尔字母在内的682个字符
  • GBK即汉字内码扩展规范,共收入21886个汉字和图形符号
  • GB8030与GB2312-1980和GBK兼容,共收录汉字70244个,是一二四字节变长编码

可看出支持的汉字范围:GB18030>GBK>GB2312

世界所有语言统一到一套编码中,这套编码就是Unicode编码。Unicode编码使用两个字节(16位bit)表示一个字符,比较偏僻的字符需要使用4个字节。

几乎所有的系统、编程语言都默认支持Unicode。如果一段纯英文文本,Unicode会占用比ASCII码多一倍的空间!UTF编码将一个Unicode字符编码成1-6个字节,常用的英文字母被编译成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。UTF编码有三种:

  • UTF-8:使用1、2、3、4个字节表示所有符号,优先使用1个字节,若无法满足,则增加一个字节,最多4个字节 。英文占1个字节、欧洲语系占2个字节、东亚占3个字节,其他特殊字符占4个字节。
  • UTF-16:使用2、4个字节表示所有符号,优先使用2个字节,否则使用4个字节表示。
  • UTF-32:使用4个字节表示所有字符。

 # 汉字的“汉”,在UTF-8字符集中3个字节
 list("汉".encode("UTF-8"))
 # [230, 177, 137]

而英文无论采用哪种编码,都是一致的。如果使用纯英文编写代码,就基本不会遇到编码问题:

 print(list("a".encode("ascii")))
 # [97]
 print(list("a".encode("gbk")))
 # [97]
 print(list("a".encode("utf-8")))
 # [97]

Python语言的with...as...用

 with open("a.txt") as file:
     data = file.read()

默认编码可以通过sys.getdefaultencoding()来查看Python解释器会用的默认编码

 import sys
 print(sys.getdefaultencoding())
 # utf-8

说明电脑上Python解释器默认使用的是UTF-8编码,如果不指定Python解释器以何种编码解码,则默认以UTF-8方式解码源文件,因此在保存代码源文件时确保以UTF-8编码保存。

1.2、文件操作

1.2.1、普通文件操作

Python文件操作只需要一个open函数返回一个文件句柄,无需导入任何模块。

 f=open("a.txt")     # 打开文件,得到一个文件句柄,并赋值给一个变量
 print(f.read())     # 打印读取文件的内容 
 f.close()           # 关闭文件

oepn函数:

 open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True, opener=None)

  • 参数file是一个文件名称的字符串,如果文件不在程序当前的路径下,就需要在前面加上相对路径或绝对路径
  • 参数mode是一个可选参数,指示打开文件的方式,若不指定,则默认以读文本的方式打开文件:

    字符串含义
    'r'的方式打开(默认)
    'w'的方式打开文件,会先清空文件
    'X'创建一个新文件,以写方式打开
    'a'以写的方式打开文件,如果文件已存在,就在文件最后位置追加内容
    'b'以二进制方式打开,可以和读写命令共用
    't'以文本方式(默认)
    '+'以读和写方式打开文件,用于更新文件
    'U'通用的换行模式(弃用)
  • buffering是一个可选的参数,buffering=0表示关闭缓冲区(仅在二进制方式打开可用),buffering=1表示选择缓冲区(仅在文本方式打开时可用);buffering大于1时,其值代表固定大小的块缓冲区的大小。当不指定该参数时:二进制文件使用固定大小的块缓冲区,文本文件使用行缓冲区。

注意:

  • 记得使用完毕后及时关闭文件,释放资源。推荐傻瓜式操作方式:使用with关键字来帮我们管理上下文,系统会自动为我们关闭文件和处理异常

     with open('a.txt','w') as f:
         f.write("hello world")
  • open()函数是操作系统打开文件,如果没有指定编码,那么以操作系统默认编码打开;Windos下是gbk,在Linux下使utf-8。

常见的文件操作方法:

名称功能
f.read()读取所有内容,光标移动到文件末尾
f.readline()读取一行内容,光标移动到第二行首部
f.readlines()读取每一行内容,存于列表中
f.write('1111\n222\n')针对文本模式的写,需要自己写换行符
f.write('1111\n222\n'.encode('utf-8'))针对b模式的写,需要自己写换行符
f.writelines(['333\n','444\n'])文件模式
f.write([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')])b模式
f.readable()文件是否可读
f.writable()文件是否可写
f.closed文件是否关闭
f.encoding如果文件打开模式为b,则没有该属性
f.flush()立刻将文件内容从内存刷到硬盘

读取文件内位置的定位方法:

  • 通过read方法传输参数
  • 以字节为单位定位,如seek、tell等。
    • seek(x,0)表示从起始位置即文件首行首字符开始移动x个字符。
    • seek(x,1)表示从当前位置向后移动x个字符.
    • seek(-x,2)表示从文件的结尾向前移动x个字符。

# 基于seek实现类似Linux命令tail-f的功能
 import time
 with open('tmp.txt','rb') as f:
     f.seek(0,2)         # 将光标移动至文件末尾
     while True:         # 实时显示文件新增加的内容
         line = f.read()
         if line:
             print(line.decode('utf-8'),end='')
         else:
             time.sleep(0,2) # 读取完毕后短暂的睡眠
 # 当tmp.txt追加新的内容时,新内容会被程序立即打印出来

1.2.2、大文件的读取

当文件较小时,我们可以一次性全部读入内存,对文件的内容做出任意修改,再保存至磁盘:

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
	data = read_f.read()	# 全部读入内存,如果文件很大,则会很卡
	data = data.replace('str1','str2')	# 在内存中完成修改
	write_f.write(data)	# 一次性写入新文件
os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')

当文件很大时,如GB级的文本文件,我们需要用文件的可迭代方式将文件的内容逐行读入内存,在逐行写入新文件,最后使用新文件覆盖源文件。

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    for line in read_f:	# 可迭代对象f逐行操作,防止内存溢出
        line=line.replace('str1','str2')
        write_f.write(line)
os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')

处理大数据还有多种方法:

  1. 通过read(size)增加参数,指定读取的字节数。

    while True:
    	block = f.read(1024)
    	if not block:
    		break
  2. 通过readline(),每次只读一行。

    while True:
    	line = f.readline()
    	if not line:
    		break

file对象常用的参数:

函数功能
file.close()关闭文件。关闭后不能再进行读写操作
file.flush()刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件,而不是被动等待输出缓冲区写入
file.fileno()返回一个整型的文件描述符,可以用在如os模块的read方法等一些底层操作上
file.isatty()如果文件连接到一个终端设备,则返回True,否则False
file.next()返回文件下一行
file.read([size])从文件读取指定的字节数,如果为给定或为负,则读取所有
file.readline([size])读取整行,包括"\n"字符
file.readlines([sizeint])读取所有行并返回列表,若给定sizeint>0,则返回总和为sizeint字节的行,实际读取值的可能比sizeint大,因为要填充缓冲区
file.seek(offset[,whence])设置文件当前位置
file.tell()返回文件当前位置
file.truncate([size])根据size参数截取文件,size参数可选
file.write(str)将字符串写入文件,没有返回值
file.writelines(sequence)向文件写入一个序列字符串列表,如果需要换行,则加入每行的换行符

1.2.3、序列化和反序列化

  • 序列化:将数据结构或对象转换成二进制串的过程
  • 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或对象的过程

Python的pickle模块实现了基本的数据序列和反序列化。

# 序列化(将对象obj保存至文件中)。
pickle.dump(obj,file,[,protocal])

# 反序列化(从文件中恢复对象,并重构为原来的Python对象)
x=pickle.load(file)

序列化实例:

import pickle

# 使用pickle模块将数据对象保存到文件

# 字符串
data0 = "hello world"
# 列表
data1 = list(range(20))[1::2]
# 元组
data2 = ("x","y","z")
# 字典
data3 = {"a":data0,"b":data1,"c":data2}

print(data0)
print(data1)
print(data2)
print(data3)

output = open("data.pk1","wb")

# 使用默认的protocal
pickle.dump(data0,output)
pickle.dump(data1,output)
pickle.dump(data2,output)
pickle.dump(data3,output)
output.close()

反序列化演示:

import pickle

# 使用pickle模块从文件中重构Python对象
pkl_file = open("data.pk1","rb")

data0 = pickle.load(pkl_file)
data1 = pickle.load(pkl_file)
data2 = pickle.load(pkl_file)
data3 = pickle.load(pkl_file)

print(data0)
print(data1)
print(data2)
print(data3)

pkl_file.close()

1.3、读写配置文件

配置文件是供程序运行时读取配置信息的文件,用于将配置信息与程序分离

Python内置的配置文件解析器模块configparser类来解析基本的配置文件。

常见的pip配置文件如下:

[global]
index-url = https://pypi.doubanio.com/simple
trusted-host = pypi.doubanio.com

读取配置文件的信息的实例:

import configparser
config = configparser.ConfigParser()    # 实例化ConfigParser类
config.read(r"lesson/pip.ini")
print("遍历配置信息")
for section in config.sections():
    print(f"section is [{section}")
    for key in config[section]:
        print(f"key is [{key}],value is [{config[section][key]}]")  # 打印键和值

print("通过键获取相对应的值:")
print(f"index-url is [{config['global']['index-url']}]")
print(f"trusted-host is [{config['global']['trusted-host']}]")

# 上述代码通过实例化ConfigParser类读取配置文件,遍历配置文件中的section信息及键值信息,通过索引获取值信息。

相关信息写入配置文件实例:

import configparser
config = configparser.ConfigParser()

config["DEFAULT"] = {
    "ServerAliveInterval":"45",
    "Compression":"yes",
    "CompressionLevel":"9"
}

config["bitbucket.org"] = {}
config["bitbucket.org"]["User"] = "hg"

config["topsecret.server.com"] = {}
topsecret = config["topsecret.server.com"]
topsecret["Port"] = "50022"
topsecret["ForwardX11"] = "no"

config["DEFAULT"]["ForwaldX11"] = "yes"

with open("example.ini","w") as configfile:
    config.write(configfile)
with open("example.ini","r") as f:
    print(f.read())

configparser模块的接口非常直接、明确。注意以下几点:

  • section名称是区分大小写的
  • section下的键值对中键是不区分大小写的,config["bitbucket.org"]在写入时会统一变成小写user保存在文件中
  • section下的键值对中的值是不区分类型的,都是字符串,具体使用时需要转换成想要的数据类型
  • section的名称是[DEFAULT]时,其他section的键值会继承[DEFAULT]的键值信息

1.4、解析XML文件*

XML的全称是eXtensible Markup Language,意为可扩展的标记语言,是一种用于标记电子文件使其具有结构性的标记语言。被设计用来传输和存储数据,例如:

<note>
    <to>George</to>
    <form>John</form>
    <heading>Reminder</heading>
    <body>Don't forget the meeting!</body>
</note>

Python有三种方法解析XML:SAX、DOM、ElementTree

1.4.1、SAX(simple API for XML)

SAX是一种基于事件驱动的API,使用时涉及两个部分:解析器事件处理器。解析器负责读取XML文件,并向事件处理器发送相应的事件。事件处理器对相应的事件做出相应,对数据做出处理。

  • 创建一个新的XMLReader对象,parser_list是可选参数,是解析器列表xml.sax.make_parser([parser_list])
  • 自定义事件处理器,继承ContentHandler类

ContenHandler类的方法:

名称功能
characters(content)从行开始,遇到标签之前,存在字符,content的值为这些字符串 从下一个标签,遇到下一个标签之前,存在字符,content的值为这些字符串
startDocument()文档启动时调用
endDocument()解析器到达文档结尾时调用
startElement(name,attrs)遇到XML开始标签时调用,name是标签的名字,attrs是标签属性值字典
endElement(name)遇到XML结束标签时调用

语法:

xml.sax.parse(xmlfile,contenthandler[,errorhandler])
# 参数说明:
xmlstring:xml字符串
contenthandler:必须是一个ContentHandler的对象
errorhandler:如果指定该参数,则errorhandler必须是一个SAXErrorHandler对象

解析XML的例子:首先有一个example.xml:

<?xml version="1.0" encoding="UTF-8"?>
<library>
    <book id="1">
        <title>Book Title One</title>
        <author>Author A</author>
        <year>2021</year>
    </book>
    <book id="2">
        <title>Book Title Two</title>
        <author>Author B</author>
        <year>2022</year>
    </book>
    <!-- More books can be added here -->
</library>

解析代码实例:

import xml.sax

class MySAXHandler(xml.sax.ContentHandler):
    def __init__(self):
        self.current_data = ""

    def startElement(self, tag, attributes):
        print(f"Start Element: {tag}")

    def endElement(self, tag):
        print(f"End Element: {tag}")
        if tag == "title":
            print(f"Title: {self.current_data}")
            self.current_data = ""
        elif tag == "author":
            print(f"Author: {self.current_data}")
            self.current_data = ""
        elif tag == "year":
            print(f"Year: {self.current_data}")
            self.current_data = ""

    def characters(self, content):
        self.current_data += content.strip()

# 创建SAX解析器
parser = xml.sax.make_parser()
# 将我们自定义的处理类注册到解析器
parser.setContentHandler(MySAXHandler())

# 解析XML文档
parser.parse("example.xml")

SAX用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件,一次处理一个标签,无需事先全部读取整个XML文档,处理效率较高。适用场景:

  • 对大型文件进行处理
  • 只需要文件的部分内容,或者只需从文件中得到特定信息
  • 想建立自己的对象模型时

1.4.2、DOM(Document Object Model)

文件对象模型是W3C组织推荐的处理可扩展置标语言的标准编程接口。

实例:使用xml.dom.minidom解析xml文件

import xml.dom.minidom
from xml.dom.minidom import parse

# 假设我们有一个XML字符串,也可以从文件中读取
xml_string = """
<?xml version="1.0" encoding="UTF-8"?>
<library>
    <book id="1">
        <title>Book Title One</title>
        <author>Author A</author>
        <year>2021</year>
    </book>
    <book id="2">
        <title>Book Title Two</title>
        <author>Author B</author>
        <year>2022</year>
    </book>
</library>
"""

# 解析XML字符串
dom = xml.dom.minidom.parseString(xml_string)
# 文档方式:
dom = xml.dom.minidom.parse("example.xml")

# 获取<library>元素
library = dom.documentElement

# 遍历所有的<book>元素
for book in library.getElementsByTagName('book'):
    # 获取<book>的id属性
    book_id = book.getAttribute('id')
    # 获取并打印<title>元素的文本
    title = book.getElementsByTagName('title')[0].firstChild.data
    # 获取并打印<author>元素的文本
    author = book.getElementsByTagName('author')[0].firstChild.data
    # 获取并打印<year>元素的文本
    year = book.getElementsByTagName('year')[0].firstChild.data

    # 打印信息
    print(f"Book ID: {book_id}")
    print(f"Title: {title}")
    print(f"Author: {author}")
    print(f"Year: {year}")
    print()  # 打印空行以便区分每本书的信息
    
# 代码使用minidom解析器打开文档,使用getElementsByTagName方法获取所有标签并遍历子标签,逻辑上比SAX直观

1.4.3、ElementTree

ElementTree将XML数据在内存中解析成,通过树来操作XML。

import xml.etree.ElementTree as ET

tree = ET.parse("example.xml")
root = tree.getroot()
print(f"这是一个早餐菜单\n{root.attrib['year']}")

for child in root:
	print("Book:",child[0].text)
	print("Title:",child[1].text)

二、系统信息监控

Python获取系统信息的模块是psutil(process and system utilities)。

2.1、监控CPU信息

import psutil

psutil.cpu_times()				# 获取CPU(逻辑CPU的平均)占用时间的详细信息
psutil.cpu_times(percpu=True)   # 获取每个CPU占用时间的详细信息
psutil.cpu_count()      		# CPU逻辑数量
psutil.cpu_count(logical=False) # CPU物理数量
psutil.cpu_percent()        	# CPU占比
psutil.cpu_percent()        	# 每个CPU的占比

2.2、监控内存信息

psutil.virtual_memory()     # 数值以字节为单位显示,自行转换

2.3、监控磁盘信息

psutil.disk_partitions()
psutil.disk_usage('/')      # 磁盘使用情况

2.4、监控网络信息

psutil.net_io_counters()    # 获取网络读写字节数/包的个数
psutil.net_if_addrs()       # 获取网络接口信息
psutil.net_if_stats()       # 获取网络接口状态
psutil.net_connections()    # 获取当前网络连接信息

2.5、获取进程信息

for pid in psutil.pids():	# 获取所有进程的pid
    print(pid,end=',')
for proc in psutil.process_iter(attrs=['pid','name','username']):
    if proc.info['name'].startswith('Wechat'):	# 查找微信程序的相关信息
        print(proc.info)
        
# psutil.process_iter返回的是一个可迭代对象,每个元素的info是一个字典,通过其可以获取我们关心的信息:
psutil.Process(12476).cpu_times()   # 获取CPU占用
psutil.Process(12476).memory_info() # 获取内存占用,rss就是实际占用的内存
psutil.Process(12476).num_threads() # 获取线程数
psutil.Process(12476).memory_percent()  # 获取内存占比

2.6、实例:常见的实用方法

import import os
import psutil
import signal

# 按名称查找进程相关信息 1
def find_procs_by_name1(name):
    "Return a list of processes matching 'name'."
    ls = []
    for p in psutil.process_iter(attrs=['name']):
        if p.info['name'] == name:
            ls.append(p)
    return ls

# 按名称查找进程相关信息 2
def find_procs_by_name2(name):
    ls = []
    for p in psutil.process_iter(attrs=["name","exe","cmdline"]):
        if name == p.info['name'] or \
            p.info['exe'] and os.path.basename(p.info['exe']) == name or \
            p.info['cmdline'] and p.info['cmdline'][0] == name:
            ls.append(p)
    return ls

# 杀掉进程树
def kill_proc_tree(pid,sig=signal.SIGTERM,include_parent=True,timeout=None,on_terminate=None):
    if pid == os.getpid():
        raise RuntimeError("I refuse to kill myself")
    parent = psutil.Process(pid)
    children = parent.children(recursive=True)
    if include_parent:
        children.append(parent)
    for p in children:
        p.send_signal(sig)
    gone,alive = psutil.wait_procs(children,timeout=timeout,callback=on_terminate)
    return (gone,alive)

# 杀掉子进程
def reap_children(tiemout=3):
    def on_terminate(proc):
        print("process {} terminated with exit code {}".format(proc,proc.returncode))
        procs = psutil.Process().children()
        # send SIGTERM
        for p in procs:
            p.terminate()
        gone,alive = psutil.wait_procs(procs,timeout=tiemout,callback=on_terminate)
        if alive:
            # send SIGKILL
            for p in alive:
                print("process {} survived SIGTERM;trying SIGKILL" % p)
                p.kill()
            gone,alive = psutil.wait_procs(alive,timeout=tiemout,callback=on_terminate)
            if alive:
                # give up
                for p in alive:
                    print("process {} survived SIGKILL;giving up" % p)

三、文件系统监控

如某个目录被删除,或者某个文件被修改、移动、删除时需要执行一定的操作或发出警报。Python使用watchdog库来实现文件系统监控,其原理是通过操作系统的事件触发

3.1、实例

import time
from watchdog.events import *
from watchdog.observers import Observer

class FileEventHandler(FileSystemEventHandler):
    def __init__(self):
        FileSystemEventHandler.__init__(self)

    def on_moved(self, event):
        now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        if event.is_directory:
            print(f"{now}文件夹由{event.src_path}移动至{event.dest_path}")
        else:
            print(f"{now}文件由{event.src_path}移动至{event.dest_path}")

    def on_created(self, event):
        now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        if event.is_directory:
            print(f"{now}文件夹{event.src_path} 创建")
        else:
            print(f"{now}文件{event.src_path} 创建")

    def on_deleted(self, event):
        now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        if event.is_directory:
            print(f"{now}文件夹{event.src_path} 删除")
        else:
            print(f"{now}文件{event.src_path} 删除")

    def on_modified(self, event):
        now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        if event.is_directory:
            print(f"{now}文件夹{event.src_path} 修改")
        else:
            print(f"{now}文件{event.src_path} 修改")

if __name__ == '__main__':
    observer = Observer()
    path = r"d:/test"
    event_handler = FileEventHandler()
    observer.schedule(event_handler, path, True)  # True表示递归子目录
    print(f"监控目录{path}")
    observer.start()
    observer.join()

适用场景:

  • 监控文件系统中文件或目录的增、删、改情况
  • 当特定的文件被创建、删除、修改、移动时执行相应的任务

四、执行外部命令subprocess

subprocess是Python自带的模块,主要用来取代一些旧的模块或方法,如os.system等。适用subprocess模块更方便地执行操作系统支持的命令,可与其他应用程序结合适用

4.1、subprocess.run()方法*

这是官方推荐使用的方法,查看其原型:

subprocess.run(args,*,stdin=None,input=None,stdout=None,stderr=None,shell=False,cwd=None,timeout=None,check=False,encoding=None,errors=None)

该函数返回一个CompletedProcess类的实例,其常用参数:

  • args代表需要在操作系统中执行的命令。可以是字符串形式(要去shell=True),也可以是列表list类型
  • *代表可变参数,一般是列或字典形式
  • stdin、stdout、stderr指定了可执行程序的标准输入、标准输出、标准错误文件句柄。
  • shell代表程序是否需要在shell上执行
  • check设置为True表示检车命令的返回值,当返回值为非0时,就抛出CalledProcessError异常
  • timeout设置超时时间,如果超时,则强制kill掉子进程

在Linux系统中操作,实例自行查找

4.2、Popen类

Popen类的构造函数:

class subprocess.Popen(args,
	bufsize=-1, 	# 0无缓冲、1行缓冲,其他正值,缓冲区大小,负值,默认系统缓冲
	executable=None,# 一般不用
    stdin=None, 	# None没有任何重定向,继承父进程。PIPE创建管道...
    stdout=None,
    stderr=None,
    preexec_fn=None, 	# 钩子函数
    close_fds=True,		
    shell=False, 
    cwd=None, 
    env=None, 
    universal_newlines=None,
    startupinfo=None, 
    creationflags=0)

使用方法:

subprocess.Popen(["getit","abc.txt"])
subprocess.Popen("getit abc.txt")

Popen类的对象还有其他实用方法:

名称功能
poll()检查是否结束,设置返回值
wait()等待结束,设置返回值
communicate()参数是标准输入,返回标准输出和标准出错
send_signal()发送信号(主要在unix下有用)
terminate()终止进程,unix对应的SIGTERM信号,windows下调用api函数TerminateProcess()
kill()杀死进程(unix对应SIGKILL信号),windows同上
stdin stdout stderr参数中指定PIPE时,可以使用
pid进程ID
returncode进程返回值

4.3、其他方法

  • subprocess.call(*popenargs,**kwargs):call方法调用Popen()执行程序,并等待它完成
  • subprocess.check_call(*popenargs,**kwargs):调用前面的call(),如果返回值非0,则抛出异常
  • subprocess.check_output(*popenargs,**kwargs):调用Popen()执行程序,并返回其标准输出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/602611.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CentOS操作

1.如何修改主机名 方法一&#xff1a; 修改命令&#xff1a;hostnamectl set-hostname 主机名 查看命令&#xff1a;hostname 方法二和方法三都是永久改变主机名&#xff0c;需要密码验证 方法二 修改命令&#xff1a;nmcli general hostname 主机名 查看命令&#xff…

[图解]SysML和EA建模住宅安全系统-02

1 00:00:00,900 --> 00:00:02,690 这个就是一个块定义图了 2 00:00:03,790 --> 00:00:04,780 简称BDD 3 00:00:05,610 --> 00:00:08,070 实际上就是UML里面的类图 4 00:00:08,080 --> 00:00:09,950 和组件图的一个结合体 5 00:00:13,150 --> 00:00:14,690 我…

正点原子i.MX 93开发板,双核A55+M33+NPU,双路RS485FDCAN千兆网,异核/AI/工业开发!

正点原子i.MX 93开发板新品上市&#xff01;双核A55M33NPU&#xff0c;双路RS485&FDCAN&千兆网&#xff0c;异核/AI/工业开发&#xff01; NXP的i.MX系列是一系列面向多媒体和工业应用的ARM架构微处理器。从i.MX6U到i.MX93&#xff0c;这一系列经历了显著的发展&#x…

指代消解类方法梳理

概念&#xff1a; MLM&#xff1a;带遮罩的语言模型 NSP&#xff1a;单句预测&#xff0c;任务包括两个输入序列 SBO&#xff1a;分词边界目标 1.spanBERT&#xff0c;2019 spanBERT是对bert从分词到文本跨度的优化&#xff0c;主要有两方面的优化&#xff1a;&#xff08…

Stable Diffusion Ai绘画模型推荐:二次元Coriander_Mix v1大模型推荐

负tag嵌入式:EasyNegative,badhandv4 此模型经测试是写实偏3D的效果 画质灰暗的话请加&#xff1a;VAE840000 或者负tag&#xff1a;(watermark:2),(blurry:2),fat,paintings,sketches,(worst quality:2),(low quality:2),(normal quality:2),((monochrome)), ((grayscale))…

iOS xib布局

1.多次启动发现启动图和截屏的图片不一致,设置launch storyboard 不能到顶部 https://blog.csdn.net/u011960171/article/details/104053696/ 2.multipiler是比例&#xff0c;需要控制顺序1.视图&#xff0c;2父视图&#xff0c;选择宽度比例&#xff0c;默认是1 3.Aspect R…

python爬虫(二) 之 42号网汽车文章爬虫

python爬虫&#xff08;二&#xff09; 之 42号网汽车文章爬虫 今天在咸鱼上有个买家找我一个42号网汽车文章的爬虫&#xff0c;目前需求已经做完了&#xff0c;现在将这部分代码开源&#xff0c;供大家参考。爬虫能够抓取到网站上所有文章的数据&#xff0c;大概一小时左右就…

超越Scratch的梦 用心打造商业系统图形编程体验

在一个阳光明媚的上午&#xff0c;卧龙和凤雏正在公司会议室激烈地讨论着图形化编程产品在商业系统开发中的应用和改进。会议室里摆放着一些电脑和投影仪&#xff0c;方便他们展示和演示相关的内容。 “你知道图形化编程在商业系统开发中没有被广泛应用的原因吗&#xff1f;”卧…

libcity笔记:libcity/evaluator/traj_loc_pred_evaluator.py

1 构造函数 2 _check_config 检查配置是否符合评估器的要求&#xff0c;确保评估过程能够顺利执行 3 collect 4 evaluate 5 save_result & clear

创建禁止操作区域并且添加水印

css 设置 &#xff1a; 引用换成自己就好 .overlay {z-index: 1000;cursor: none; /*设置为不可点击*/user-select: none; /*设置为不可选择*/contenteditable: false; /*设置为不可编辑*/draggable: false; /*设置为不可拖动*/position: absolute;top: 0;left: 0;width: 100…

最新闲鱼小众蓝海虚拟资源,单号日入300+,三天必起店,矩阵放大月入1-2W

详情介绍 本项目售卖的虚拟资源非常小众&#xff0c;宅男的最爱&#xff0c;并且市场一片蓝海&#xff01;只需一步手机&#xff0c;随时随地操作项目&#xff0c;流量巨大&#xff0c;安装教程方法操作三天必起店&#xff0c;消息多到回不过来&#xff0c;一天轻松出个大几十单…

数字孪生涉及到的前沿技术:虚拟现实 人工智能 区块链 边缘计算。

数字孪生是各类技术的综合应用&#xff0c;除了咱们常见的传感器、数据采集、清洗、传输、建模、可视化技术外&#xff0c;还有还有一些前沿技术&#xff0c;会让数字孪生更加强大和智能&#xff0c;本文介绍几个。 虚拟现实&#xff08;Virtual Reality&#xff0c;VR&#x…

搜维尔科技:【案例分享】Xsens用于工业制造艺术创新设计平台

用户名称&#xff1a;北京理工大学 主要产品&#xff1a;Xsens MVN Awinda惯性动作捕捉系统 在设计与艺术学院的某实验室内&#xff0c;通过Xsens惯性动作捕捉&#xff0c;对人体动作进行捕捉&#xff0c;得到人体三维运动数据&#xff0c;将捕到的数据用于后续应用研究。…

【影片欣赏】【指环王】【魔戒:双塔奇谋 The Lord of the Rings: The Two Towers】

2003年发行&#xff0c;Special Extended DVD Edition Part One 1. The Foundations of Stone 2. Elven Rope 3. The Taming of Smeagol 4. The Uruk-hai 5. The Three Hunters 6. The Burning of the Westfold 7. Massacre at the Fords of Isen 8. The Banishment of Eomer …

stable diffusion 之云端部署攻略

本文主要介绍stable diffusion云端产品以及使用步骤 ℹ️整合安装包、模型资源见文末~ megaease cloud&#xff08;强烈推荐&#xff09; 优点&#xff1a; 集成了常用大模型和插件、VAE3080显卡配置&#xff0c;费用大概0.48元/小时&#xff0c;可随时暂停&#xff0c;暂停…

图片如何压缩到500kb以下?3步完成图片压缩

在日常生活和工作中&#xff0c;经常需要处理各种图片&#xff0c;而有时候图片文件过大&#xff0c;不仅占用了大量的存储空间&#xff0c;还可能影响文件的传输速度和加载速度。因此&#xff0c;如何将图片压缩到500kb以内成为了许多人的需求&#xff0c;普通的图片压缩可能没…

如何在没有备份的情况下恢复 Mac 上丢失的数据

如果您因意外删除、错误格式化硬盘或文件损坏而丢失了重要的、感伤的文件、照片或音乐&#xff0c;那么这可能会令人非常痛苦。幸运的是&#xff0c;您有几个选择。 您的 Mac 位于数字宇宙的中心。您可能会在上面留下照片和视频形式的记忆&#xff0c;以及来自您不再见面的朋友…

Ubuntu16.04 离线安装CDH6.2.1

1. 离线包工作 下载Cloudera Manager安装包&#xff0c;地址&#xff1a;https://archive.cloudera.com/cm6/6.2.1/repo-as-tarball/ cm6.2.1-ubuntu1604.tar.gz下载CDH6.2.1安装包&#xff0c;地址&#xff1a;https://archive.cloudera.com/cdh6/6.2.1/parcels/ CDH-6.2.1-1.…

IP 地址追踪工具促进有效的 IP 管理

网络 IP 地址空间的结构、扫描和管理方式因组织的规模和网络需求而异&#xff0c;网络越大&#xff0c;需要管理的 IP 就越多&#xff0c;IP 地址层次结构就越复杂。因此&#xff0c;如果没有 IP 地址管理&#xff08;IPAM&#xff09;解决方案&#xff0c;IP 资源过度使用和地…

Java面试八股文(SpringCloud篇)

****************************************************