You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python处理Linux进程执行时间:转timedelta及通过PID获取简化格式

处理Linux进程执行时间:搞定ps的破格式,用纯Python标准库更稳

先解决ps输出的格式解析问题

如果你非要用ps命令的输出,得先处理那三种不固定的etime格式:

  • 1-01:12:23 → 天数-时:分:秒
  • 05:39:03 → 时:分:秒
  • 15:06 → 分:秒

直接写个解析函数转成timedelta:

from datetime import timedelta

def parse_ps_etime(etime_str):
    days = 0
    # 拆分天数和时间部分
    if '-' in etime_str:
        days_part, time_part = etime_str.split('-', 1)
        days = int(days_part)
        time_components = time_part.split(':')
    else:
        time_components = etime_str.split(':')
    
    # 根据冒号拆分后的数量分配时、分、秒
    match len(time_components):
        case 3:
            hours, minutes, seconds = map(int, time_components)
        case 2:
            hours = 0
            minutes, seconds = map(int, time_components)
        case _:
            hours = minutes = 0
            seconds = int(time_components[0]) if time_components else 0
    
    return timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)

测试用例:

  • parse_ps_etime("1-01:12:23") → timedelta(days=1, hours=1, minutes=12, seconds=23)
  • parse_ps_etime("05:39:03") → timedelta(hours=5, minutes=39, seconds=3)
  • parse_ps_etime("15:06") → timedelta(minutes=15, seconds=6)

更靠谱的方案:放弃ps,直接读/proc文件系统

ps的etime格式确实坑,长期运行的进程可能出各种变种。直接读Linux的/proc虚拟文件系统才是正解——完全用Python标准库(os、sys、time)就能实现,不用调用外部命令,格式绝对稳定。

逻辑:

  1. 从/proc/uptime拿系统已运行的秒数,结合当前时间算出系统启动时间
  2. 从/proc/<pid>/stat的第22个字段(starttime)拿到进程启动时的系统时钟滴答数(jiffies),转成秒后加上系统启动时间,得到进程的精确启动时间
  3. 当前时间减去进程启动时间,直接得到timedelta对象,随便做运算

代码:

import os
import sys
import time
from datetime import datetime, timedelta

def get_process_runtime(pid):
    try:
        # 获取系统时钟频率(默认100,大部分Linux系统都是这个)
        clk_tck = sys.sysconf(sys.sysconf_names['SC_CLK_TCK']) if hasattr(sys, 'sysconf') else 100
        # 读取系统已运行秒数
        with open('/proc/uptime', 'r') as f:
            uptime_sec = float(f.read().split()[0])
        system_boot = datetime.now() - timedelta(seconds=uptime_sec)
        
        # 读取进程stat信息
        with open(f'/proc/{pid}/stat', 'r') as f:
            stat_fields = f.read().split()
        # starttime是第22个字段(索引从1开始,所以是21)
        start_jiffies = int(stat_fields[21])
        start_sec = start_jiffies / clk_tck
        process_start = system_boot + timedelta(seconds=start_sec)
        
        # 返回运行时长
        return datetime.now() - process_start
    except (FileNotFoundError, IndexError, ValueError, PermissionError):
        # 处理PID不存在、权限不够、格式异常等情况
        return None

为啥这个更稳?

  • 完全避免了外部命令的输出格式不稳定问题
  • 纯Python标准库,不需要额外依赖
  • 直接得到timedelta对象,加减运算直接用,不用再转格式

比如调用get_process_runtime(1)就能拿到init进程的运行时长,直接是可操作的timedelta。

内容的提问来源于stack exchange,提问作者intrigued_66

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:20:37