如何通过POSIX标准从Shell获取指定PID的启动时间以验证进程身份?
解决思路
核心是通过进程的运行时长(etime)反推启动时间,以此区分原进程和复用PID的新进程:
- 获取当前时间的Epoch秒数
- 获取目标PID的运行时长(etime)并转换为总秒数
- 用当前时间减去运行时长,得到进程启动的Epoch秒数
- 与记录的启动时间对比,判断是否为原进程
具体实现
假设你的记录文件每行格式是PID\tSTARTTIME,可以用以下Shell脚本处理:
#!/bin/sh # 替换为你的记录文件路径 record_file="process_records.txt" while IFS=$'\t' read -r pid recorded_start; do # 先检查PID是否存在 if ! kill -0 "$pid" 2>/dev/null; then echo "PID $pid: 进程已终止" continue fi # 获取当前时间的Epoch秒数 current_epoch=$(date +%s) if [ -z "$current_epoch" ]; then echo "PID $pid: 无法获取当前时间" continue fi # 获取进程运行时长etime,去除前后空格 etime=$(ps -o etime= -p "$pid" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') if [ -z "$etime" ]; then echo "PID $pid: 无法获取运行时长" continue fi # 将etime转换为总秒数(用awk处理格式拆分) run_seconds=$(echo "$etime" | awk ' { split($0, parts, /[-:]/) len = length(parts) sec = 0 if (len == 4) { sec += parts[1] * 86400 + parts[2] * 3600 + parts[3] * 60 + parts[4] } else if (len == 3) { sec += parts[1] * 3600 + parts[2] * 60 + parts[3] } else if (len == 2) { sec += parts[1] * 60 + parts[2] } print sec }') # 计算启动时间的Epoch秒数 start_epoch=$((current_epoch - run_seconds)) # 对比记录的启动时间 if [ "$start_epoch" -eq "$recorded_start" ]; then echo "PID $pid: 原进程存活" else echo "PID $pid: PID已被新进程复用" fi done < "$record_file"
注意事项
ps -o etime=是POSIX标准支持的选项,不会出现lstart参数的兼容性问题- 计算过程忽略了闰年、夏令时等时间调整的影响,对绝大多数场景足够准确;若需更高精度,需结合系统时间调整记录,但这超出了POSIX标准范围
- 少数系统中,进程运行时长超100天时,etime会显示为
DDDDD HH:MM:SS格式,此时需调整awk的拆分逻辑(先按空格拆分天数与时分秒)
内容的提问来源于stack exchange,提问作者Fravadona
相关产品推荐
相关产品推荐

