劇照:約定的夢幻島(第二季)
楔子Python 有一個第三方模組:psutil,專門用來獲取作業系統以及硬體相關的資訊,比如:CPU、磁碟、網路、記憶體等等。
首先我們要安裝,直接 pip install psutil 即可,安裝之後來看看它的用法。
CPU 相關獲取 CPU 的邏輯數量
import psutilprint(psutil.cpu_count()) # 12
獲取 CPU 的物理核心數量
import psutilprint(psutil.cpu_count(logical=False)) # 6
結果為 6,說明是 6 核超執行緒;如果 CPU 的物理核心數 和 邏輯數相等,也為 12,則說明是 12 核非超執行緒。
統計 CPU 的使用者/系統/空閒時間
import psutilprint(psutil.cpu_times()) # scputimes(user=65531.796875, system=42440.76562500023, idle=1783904.3593749998, interrupt=5676.375, dpc=1846.609375)# psutil.cpu_times_percent() 功能與之類似, 只不過返回的比例
返回的是一個 namedtuple,後面凡是結構長的和這裡類似的,都是 namedtuple。
檢視 CPU 的使用率
import psutilfor x in range(3): # interval:表示每隔0.5s重新整理一次 # percpu:表示檢視所有的cpu使用率 print(psutil.cpu_percent(interval=0.5, percpu=True))"""[6.1, 6.2, 9.4, 3.1, 0.0, 0.0, 0.0, 6.2, 3.1, 3.1, 3.1, 0.0][0.0, 0.0, 6.1, 0.0, 6.1, 3.0, 0.0, 3.0, 3.0, 3.0, 0.0, 9.1][0.0, 0.0, 6.2, 3.1, 3.1, 0.0, 3.1, 3.1, 3.1, 3.1, 0.0, 0.0]"""# 我這裡cpu的邏輯數量是12, 所以每個列表裡面有12個元素
檢視 CPU 的統計資訊,包括上下文切換、中斷、軟中斷,以及系統呼叫次數等等
import psutilprint(psutil.cpu_stats())# scpustats(ctx_switches=2912990332, interrupts=4290503758, soft_interrupts=0, syscalls=2698751096)
檢視 CPU 的頻率
import psutilprint(psutil.cpu_freq()) # scpufreq(current=2208.0, min=0.0, max=2208.0)
記憶體相關
檢視記憶體使用情況
import psutilprint(psutil.virtual_memory()) # svmem(total=17029259264, available=8437215232, percent=50.5, used=8592044032, free=8437215232)
total: 總記憶體available: 可用記憶體percent: 記憶體使用率used: 已使用的記憶體檢視交換記憶體資訊
import psutilprint(psutil.swap_memory())# sswap(total=19579396096, used=15708250112, free=3871145984, percent=80.2, sin=0, sout=0)
關於物理記憶體和交換記憶體之間的關係。
物理記憶體:就是實際的記憶體條提供的臨時資料儲存空間,在 Windows 上右鍵點選計算機,再點選屬性時,上面顯示的安裝記憶體(RAM)就是電腦的物理記憶體。這些記憶體是實際存在的,在你不給機器增加記憶體條的時候是不會改變的。
交換記憶體:交換記憶體是專門用來臨時儲存資料的,通常在頁面排程和交換程序資料時使用。相當於在進行記憶體整理的時候,會先把部分資料放在硬碟的某個地方,類似我們整理衣櫃,衣服一多直接整理會很麻煩,因此會先把部分衣服放在其他地方,等衣櫃裡的衣服整理完了再把放在其它地方的衣服拿回來。這個其他地方放在計算機中則代表硬碟的某個地方,也就是我們所說的交換區。通常當使用交換記憶體時,是因為物理記憶體不足,正所謂衣櫃,如果足夠大的話就沒必要拿出部分衣服放在其它地方, 直接在衣櫃裡就能解決了。
虛擬記憶體:首先,如果想要操作檔案,可執行程式等等,那麼首先要把它們從磁碟上讀取到記憶體中,因此 CPU 除了自己的那一部分小小的空間外,要想操作資料,只能操作記憶體裡的資料。但是當記憶體不夠了,那麼便會在硬碟上開闢一份虛擬記憶體,將物理記憶體裡的部分資料放在虛擬記憶體當中。硬碟的空間很大,即使普通電腦安裝的固態硬碟也有一百個 G,因此可以拿出一部分充當虛擬記憶體。不過虛擬記憶體雖說是記憶體,但畢竟在硬碟上,速度絕對和 CPU 直接從物理記憶體裡讀取資料的速度相差甚遠。這也是為什麼那些大型網站將經常被訪問的一些資料放在 Redis 快取裡,而不是放在硬碟或者資料庫上。
磁碟相關檢視磁碟分割槽、磁碟使用率和磁碟 IO 資訊
from pprint import pprintimport psutilpprint(psutil.disk_partitions())"""[sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='D:\\', mountpoint='D:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='E:\\', mountpoint='E:\\', fstype='NTFS', opts='rw,fixed')]"""# 可以看到一共有三個碟符,fstype表示檔案系統格式是NTFS,opts中的rw表示可讀寫# 裡面有一個引數 all, 預設為 False, 如果指定為 True, 那麼返回的內容還會包含 /proc 等特殊檔案系統的掛載資訊# 由於我這裡是 Windows, 所以兩者沒區別
檢視某個磁碟使用情況
import psutilprint(psutil.disk_usage("C:\\"))# sdiskusage(total=267117391872, used=88213196800, free=178904195072, percent=33.0)
檢視磁碟 IO 統計資訊
from pprint import pprintimport psutilpprint(psutil.disk_io_counters())# sdiskio(read_count=1270037, write_count=2146886, read_bytes=34637616128, write_bytes=53505994240, read_time=551, write_time=1258)
read_count: 讀次數write_count: 寫次數read_bytes: 讀的位元組數write_bytes: 寫的位元組數read_time: 讀時間write_time: 寫時間
預設返回的是所有磁碟加起來的統計資訊,我們可以指定 perdisk=True,則分別列出每一個磁碟的統計資訊。
from pprint import pprintimport psutilpprint(psutil.disk_io_counters(perdisk=True))"""{'PhysicalDrive0': sdiskio(read_count=1262459, write_count=2149207, read_bytes=34598280704, write_bytes=53708976128, read_time=532, write_time=1261), 'PhysicalDrive1': sdiskio(read_count=7702, write_count=98, read_bytes=41695232, write_bytes=4730880, read_time=19, write_time=0)}"""
網路相關
檢視網絡卡的網路 IO 統計資訊
from pprint import pprintimport psutilpprint(psutil.net_io_counters())"""snetio(bytes_sent=536008958, bytes_recv=8676204996, packets_sent=2725499, packets_recv=7225179, errin=0, errout=9, dropin=0, dropout=0)"""# bytes_sent: 傳送的位元組數# bytes_recv: 接收的位元組數# packets_sent: 傳送的包資料量# packets_recv: 接收的包資料量# errin: 接收包時, 出錯的次數# errout: 傳送包時, 出錯的次數# dropin: 接收包時, 丟棄的次數# dropout: 傳送包時, 丟棄的次數# 裡面還有一個 pernic 引數, 如果為 True, 則列出所有網絡卡的資訊pprint(psutil.net_io_counters(pernic=True))"""{'Loopback Pseudo-Interface 1': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'WLAN': snetio(bytes_sent=534497477, bytes_recv=8678905297, packets_sent=2706204, packets_recv=7244187, errin=0, errout=0, dropin=0, dropout=0), '乙太網': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), '乙太網 2': snetio(bytes_sent=3612804, bytes_recv=7955853, packets_sent=32818, packets_recv=26442, errin=0, errout=9, dropin=0, dropout=0), '本地連線* 2': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), '本地連線* 3': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), '藍芽網路連線': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0)}"""
檢視網路介面資訊
from pprint import pprintimport psutil# 以字典的形式返回網絡卡的配置資訊, 包括 IP 地址、Mac地址、子網掩碼、廣播地址等等pprint(psutil.net_if_addrs())"""{'Loopback Pseudo-Interface 1': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='::1', netmask=None, broadcast=None, ptp=None)], 'WLAN': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='04-EA-56-8C-36-24', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.8.115', netmask='255.255.255.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fd94:e9ee:f230:6e00:55c9:8d1e:f23d:3acc', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fd94:e9ee:f230:6e00:dc07:1987:2395:d871', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::55c9:8d1e:f23d:3acc', netmask=None, broadcast=None, ptp=None)], '乙太網': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='9C-7B-EF-15-FC-2F', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='10.254.61.6', netmask='255.255.255.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.54.71', netmask='255.255.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::4826:a6a6:b5f4:3647', netmask=None, broadcast=None, ptp=None)], '乙太網 2': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='00-FF-B3-BA-07-AE', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='2.0.1.32', netmask='255.255.255.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::cc21:26c6:9327:1355', netmask=None, broadcast=None, ptp=None)], '本地連線* 2': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='04-EA-56-8C-36-25', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.45.234', netmask='255.255.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::d958:b3fe:ef3d:2dea', netmask=None, broadcast=None, ptp=None)], '本地連線* 3': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='06-EA-56-8C-36-24', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.41.166', netmask='255.255.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::6474:c583:1626:29a6', netmask=None, broadcast=None, ptp=None)], '藍芽網路連線': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='04-EA-56-8C-36-28', netmask=None, broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET: 2>, address='169.254.135.205', netmask='255.255.0.0', broadcast=None, ptp=None), snicaddr(family=<AddressFamily.AF_INET6: 23>, address='fe80::5cbd:8913:7499:87cd', netmask=None, broadcast=None, ptp=None)]}"""# 返回網絡卡的詳細資訊, 包括是否啟動、通訊型別、傳輸速度、mtupprint(psutil.net_if_stats())"""{'Loopback Pseudo-Interface 1': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1073, mtu=1500), 'WLAN': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=866, mtu=1500), '乙太網': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500), '乙太網 2': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=10, mtu=1400), '本地連線* 2': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500), '本地連線* 3': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=0, mtu=1500), '藍芽網路連線': snicstats(isup=False, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=3, mtu=1500)}"""
檢視當前機器的網路連線
from pprint import pprintimport psutil# 以列表的形式返回每個網路連線的詳細資訊# 裡面接受一個引數, 預設是 "inet", 當然我們也可以指定為其它, 比如 "tcp"pprint(psutil.net_connections())"""[sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='0.0.0.0', port=1024), raddr=(), status='LISTEN', pid=940), sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='0.0.0.0', port=5432), raddr=(), status='LISTEN', pid=7620), sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=10637), raddr=addr(ip='127.0.0.1', port=10638), status='ESTABLISHED', pid=10152), sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=10613), raddr=addr(ip='127.0.0.1', port=10612), status='ESTABLISHED', pid=10152), sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=<SocketKind.SOCK_DGRAM: 2>, laddr=addr(ip='::', port=5353), raddr=(), status='NONE', pid=8820), sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=54541), raddr=(), status='LISTEN', pid=2908), sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, .... .... ....]"""# 是不是很方便呢? 在 Linux 中有兩個命令可以做到這一點, netstat 和 ss# $ netstat -nat# $ ss -nat# 但是在生產環境中, 線上伺服器很多都是最小化安裝, 並不能保證每臺機器上都有 ss 或者 netstat 命令, 而這個時候 psutil 就派上用場了
檢視當前登入的使用者資訊
from pprint import pprintimport psutilpprint(psutil.users()) # [suser(name='satori', terminal=None, host='0.0.0.0', started=1609841661.0, pid=None)]
name: 使用者名稱terminal: 終端host: 主機地址started: 登入時間pid: 程序id
檢視系統的啟動時間
from pprint import pprintimport psutilimport datetimepprint(psutil.boot_time()) # 1585282271.0print(datetime.datetime.fromtimestamp(psutil.boot_time())) # 2020-03-27 12:11:11
程序管理
psutil 還提供了很多和程序管理相關的功能函式,非常的豐富,我們來看一下。
檢視當前存在的所有程序的 pid
from pprint import pprintimport psutilpprint(psutil.pids())"""[0, 4, 144, 512, 536, 632, 640, 664, 696, 768, 776, ... ... ...]"""
檢視某個程序是否存在
from pprint import pprintimport psutilpprint(psutil.pid_exists(22333)) # Falsepprint(psutil.pid_exists(0)) # True
返回所有程序(Process)物件組成的迭代器
from pprint import pprintimport psutilpprint(psutil.process_iter()) # <generator object process_iter at 0x000001F12032C9E0>
根據 pid 獲取一個程序對應的 Process 物件
from pprint import pprintimport psutilpprint(psutil.Process(pid=0)) # psutil.Process(pid=0, name='System Idle Process', started='2020-2-27 09:07:47')
獲取程序相關的具體資訊
我們說根據 pid 可以獲取一個程序對應的 Process 物件,而這個物件裡面包含了該程序的全部資訊。
from pprint import pprintimport psutilp = psutil.Process(pid=16948)# 程序名稱print(p.name()) # WeChat.exe# 程序的exe路徑print(p.exe()) # D:\WeChat\WeChat.exe# 程序的工作目錄print(p.cwd()) # D:\WeChat# 程序啟動的命令列print(p.cmdline()) # ['D:\\WeChat\\WeChat.exe']# 當前程序idprint(p.pid) # 16948# 父程序idprint(p.ppid()) # 11700# 父程序print(p.parent()) # psutil.Process(pid=11700, name='explorer.exe', started='09:19:06')# 子程序列表pprint(p.children())"""[psutil.Process(pid=17452, name='WeChatWeb.exe', started='09:21:02'), psutil.Process(pid=16216, name='WeChatApp.exe', started='09:21:40'), psutil.Process(pid=13452, name='SogouCloud.exe', started='09:22:14')]"""# 程序狀態print(p.status()) # running# 程序使用者名稱print(p.username()) # LAPTOP-264ORES3\satori# 程序建立時間,返回時間戳print(p.create_time()) # 1561775539.0# 程序終端# 在windows上無法使用try: print(p.terminal())except Exception as e: print(e) # 'Process' object has no attribute 'terminal'# 程序使用的cpu時間print(p.cpu_times()) # pcputimes(user=133.3125, system=188.203125, children_user=0.0, children_system=0.0)# 程序所使用的的記憶體print(p.memory_info())"""pmem(rss=128634880, vms=117067776, num_page_faults=12193918, peak_wset=263921664, wset=128634880, peak_paged_pool=1398584, paged_pool=1329936, peak_nonpaged_pool=313896, nonpaged_pool=152192, pagefile=117067776, peak_pagefile=201670656, private=117067776)"""# 程序開啟的檔案pprint(p.open_files())"""[popenfile(path='C:\\Users\\satori\\Documents\\WeChat Files\\wxid_3ksrps1o47mf22\\Msg\\Media.db-wal', fd=-1), popenfile(path='C:\\Users\\satori\\AppData\\Roaming\\Tencent\\WeChat\\All Users\\CefResources\\2581\\qb_200_percent.pak', fd=-1), popenfile(path='C:\\Users\\satori\\Documents\\WeChat Files\\wxid_3ksrps1o47mf22\\Msg\\Multi\\MSG0.db-shm', fd=-1), popenfile(path='C:\\Program Files\\WindowsApps\\Microsoft.LanguageExperiencePackzh-CN_18362.28.87.0_neutral__8wekyb3d8bbwe\\Windows\\System32\\zh-CN\\dui70.dll.mui', fd=-1), popenfile(path='C:\\Users\\satori\\Documents\\WeChat Files\\wxid_3ksrps1o47mf22\\Msg\\Multi\\MediaMSG2.db-shm', fd=-1), popenfile(path='C:\\Users\\satori\\Documents\\WeChat Files\\wxid_3ksrps1o47mf22\\Msg\\Emotion.db-wal', fd=-1), popenfile(path='C:\\Windows\\Fonts\\msyh.ttc', fd=-1), ...... ...... ...... ]"""# 程序相關的網路連線pprint(p.connections())"""[pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.8.115', port=5162), raddr=addr(ip='183.3.234.107', port=443), status='ESTABLISHED'), pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.8.115', port=13856), raddr=addr(ip='61.151.168.204', port=80), status='CLOSE_WAIT'), pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='0.0.0.0', port=8680), raddr=(), status='LISTEN')]"""# 程序內的執行緒數量,這個程序開啟了多少個執行緒print(p.num_threads()) # 66# 這個程序內的所有執行緒資訊pprint(p.threads())"""[pthread(id=13340, user_time=113.328125, system_time=179.015625), pthread(id=17120, user_time=0.0, system_time=0.0625), pthread(id=7216, user_time=0.15625, system_time=0.515625), pthread(id=13360, user_time=0.703125, system_time=0.21875), pthread(id=10684, user_time=0.015625, system_time=0.078125), pthread(id=13552, user_time=2.9375, system_time=0.171875), pthread(id=12620, user_time=0.265625, system_time=0.296875), pthread(id=14492, user_time=0.015625, system_time=0.03125), pthread(id=14568, user_time=0.0, system_time=0.046875), pthread(id=17112, user_time=0.015625, system_time=0.0625), pthread(id=9344, user_time=0.0, system_time=0.015625), pthread(id=13544, user_time=0.0, system_time=0.0), pthread(id=10028, user_time=0.078125, system_time=0.125), pthread(id=4920, user_time=0.015625, system_time=0.0625), pthread(id=5744, user_time=0.0, system_time=0.015625), pthread(id=7044, user_time=0.0, system_time=0.0), pthread(id=14064, user_time=0.0, system_time=0.0), pthread(id=11916, user_time=0.0, system_time=0.0), pthread(id=1316, user_time=0.0, system_time=0.0), pthread(id=18100, user_time=0.0, system_time=0.0), pthread(id=2992, user_time=0.0, system_time=0.0), pthread(id=8956, user_time=0.0, system_time=0.0), pthread(id=8588, user_time=0.03125, system_time=0.03125), pthread(id=3944, user_time=0.0, system_time=0.03125), pthread(id=15828, user_time=0.0, system_time=0.015625), pthread(id=7348, user_time=0.0, system_time=0.03125), pthread(id=3400, user_time=0.0, system_time=0.015625), pthread(id=8628, user_time=0.0, system_time=0.0), pthread(id=2400, user_time=0.0, system_time=0.0), pthread(id=9432, user_time=1.28125, system_time=0.171875), pthread(id=11544, user_time=0.0, system_time=0.015625), pthread(id=12348, user_time=2.96875, system_time=3.78125), pthread(id=3444, user_time=0.0, system_time=0.0), pthread(id=17476, user_time=0.0, system_time=0.0), pthread(id=15856, user_time=0.0, system_time=0.015625), pthread(id=12248, user_time=0.0, system_time=0.0), pthread(id=17280, user_time=0.0, system_time=0.0), ...... ...... ...... ]"""# 程序的環境變數pprint(p.environ())"""{'ALLUSERSPROFILE': 'C:\\ProgramData', 'APPDATA': 'C:\\Users\\satori\\AppData\\Roaming', 'COMMONPROGRAMFILES': 'C:\\Program Files (x86)\\Common Files', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'COMPUTERNAME': 'LAPTOP-264ORES3', 'COMSPEC': 'C:\\WINDOWS\\system32\\cmd.exe', 'DRIVERDATA': 'C:\\Windows\\System32\\Drivers\\DriverData', 'GOPATH': 'C:\\Users\\satori\\go', 'HOMEDRIVE': 'C:', 'HOMEPATH': '\\Users\\satori', 'LOCALAPPDATA': 'C:\\Users\\satori\\AppData\\Local', 'LOGONSERVER': '\\\\LAPTOP-264ORES3', 'NUMBER_OF_PROCESSORS': '12', 'ONEDRIVE': 'C:\\Users\\satori\\OneDrive', 'ONEDRIVECONSUMER': 'C:\\Users\\satori\\OneDrive', 'ONLINESERVICES': 'Online Services', 'OS': 'Windows_NT', 'PATH': 'C:\\Program Files (x86)\\Intel\\Intel(R) Management Engine ' 'Components\\iCLS\\;C:\\Program Files\\Intel\\Intel(R) Management ' 'Engine ' 'Components\\iCLS\\;C:\\windows\\system32;C:\\windows;C:\\windows\\System32\\Wbem;C:\\windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\windows\\System32\\OpenSSH\\;C:\\Program ' 'Files (x86)\\Intel\\Intel(R) Management Engine ' 'Components\\DAL;C:\\Program Files\\Intel\\Intel(R) Management Engine ' 'Components\\DAL;C:\\Program Files (x86)\\NVIDIA ' 'Corporation\\PhysX\\Common;C:\\Program ' 'Files\\Intel\\WiFi\\bin\\;C:\\Program Files\\Common ' 'Files\\Intel\\WirelessCommon\\;C:\\python37;c:\\python37\\Scripts;C:\\Program ' 'Files\\Git\\cmd;E:\\instantclient_10_2;C:\\Program ' 'Files\\Redis\\;D:\\ffmpeg\\bin;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Go\\bin;C:\\MingW\\bin;C:\\Users\\satori\\.cargo\\bin;C:\\python37\\Scripts\\;C:\\python37\\;C:\\python38\\Scripts\\;C:\\python38\\;C:\\Users\\satori\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Users\\satori\\go\\bin', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC', 'PLATFORMCODE': 'AN', 'PROCESSOR_ARCHITECTURE': 'x86', 'PROCESSOR_ARCHITEW6432': 'AMD64', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 158 Stepping 10, GenuineIntel', 'PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '9e0a', 'PROGRAMDATA': 'C:\\ProgramData', 'PROGRAMFILES': 'C:\\Program Files (x86)', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'PROGRAMW6432': 'C:\\Program Files', 'PSMODULEPATH': 'C:\\Program ' 'Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules', 'PUBLIC': 'C:\\Users\\Public', 'REGIONCODE': 'APJ', 'SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SYSTEMROOT': 'C:\\WINDOWS', 'TBS_CONTENT_MAIN_RUNNER_INITIALIZED': '1', 'TEMP': 'C:\\Users\\satori\\AppData\\Local\\Temp', 'TMP': 'C:\\Users\\satori\\AppData\\Local\\Temp', 'USERDOMAIN': 'LAPTOP-264ORES3', 'USERDOMAIN_ROAMINGPROFILE': 'LAPTOP-264ORES3', 'USERNAME': 'satori', 'USERPROFILE': 'C:\\Users\\satori', 'VS140COMNTOOLS': 'C:\\Program Files (x86)\\Microsoft Visual Studio ' '14.0\\Common7\\Tools\\', 'WINDIR': 'C:\\WINDOWS', 'WXDRIVE_START_ARGS': '--wxdrive-setting=0 --disable-gpu ' '--disable-software-rasterizer ' '--enable-features=NetworkServiceInProcess'}"""# 結束程序, 返回 None, 執行之後微信就會被強制關閉, 當然這裡就不試了# print(p.terminal()) # None
我們還可以呼叫 psutil.test 來模擬 ps 命令。
import psutilpsutil.test()"""USER PID %MEM VSZ RSS NICE STATUS START TIME CMDLINESYSTEM 0 0.0 60.0K 8.0K runni Dec30 00:39 System Idle PSYSTEM 4 0.0 236.0K 1.4M runni Dec30 14:32 System 144 0.2 8.1M 32.2M runni Dec30 00:03 Registry 512 0.0 1.1M 304.0K runni Dec30 00:00 smss.exe 536 0.0 912.0K 1.0M runni Dec30 00:00 svchost.exe 632 0.1 13.0M 15.0M runni Dec30 00:29 svchost.exe 640 0.0 2.1M 1.3M runni Dec30 00:00 fontdrvhost.esatori 664 0.1 26.1M 17.1M 32 runni 09:19 00:02 C:\WINDOWS\Sy 696 0.0 6.7M 3.8M runni Dec30 00:04 WUDFHost.exe 768 0.0 1.9M 1.9M runni Dec30 00:26 csrss.exe.............................................................................................................."""
它是怎麼做的呢?還記得我們之前說的 process_iter 嗎?會返回所有程序的 Process 物件,直接依次輸出裡面的資訊即可。同理,我們也可以透過 process_iter 找到某一個程序對應的程序 id。
import psutilfor prcs in psutil.process_iter(): if prcs.name().lower() == "wechat.exe": print(prcs.pid)"""16948"""# 有了這個騷操作之後,我們便可以透過程序 id 找到對應的程序# 然後修改裡面的資料
小結
總的來說,這個庫是非常強大的,很好用,可以獲取很多底層的資訊。