Arch Linux命令行电池信息工具中电池剩余运行时长与充满时长计算方案问询
Arch Linux命令行电池信息工具中电池剩余运行时长与充满时长计算方案问询
嘿,针对你在Arch Linux命令行项目里遇到的电池时长计算问题,我来分享几个原生、可靠的方案——毕竟Linux的sysfs文件系统已经把这些底层数据直接暴露给我们了,完全不用依赖第三方工具,适配性还强。
一、计算放电时的剩余运行时长
Linux系统会把电池的实时数据放在/sys/class/power_supply/BAT0/目录下(如果你的笔记本有多个电池,可能是BAT1、BAT2,可自行调整),核心用到这几个文件:
status:判断当前电池状态(Discharging/Charging/Full等)energy_now:当前剩余电量(单位:微瓦时,μWh)power_now:当前实时功耗(单位:微瓦,μW)
计算逻辑
当电池处于Discharging状态时,剩余运行时长 = 剩余电量 / 当前功耗,结果直接是小时数,你可以再转成小时+分钟的格式。
Bash示例代码
# 定义电池路径,可根据实际情况调整为BAT1等 BAT_PATH="/sys/class/power_supply/BAT0" # 获取当前电池状态 STATUS=$(cat "$BAT_PATH/status") if [ "$STATUS" = "Discharging" ]; then ENERGY_NOW=$(cat "$BAT_PATH/energy_now") POWER_NOW=$(cat "$BAT_PATH/power_now") # 处理功耗为0的特殊情况(比如待机) if [ "$POWER_NOW" -eq 0 ]; then echo "当前功耗为0,无法计算剩余运行时长" exit 1 fi # 计算时长,保留两位小数 RUNTIME_HOURS=$(echo "scale=2; $ENERGY_NOW / $POWER_NOW" | bc) # 拆分小时和分钟 HOURS=$(echo "$RUNTIME_HOURS" | cut -d. -f1) MINUTES=$(echo "scale=0; ($RUNTIME_HOURS - $HOURS) * 60" | bc) echo "预计剩余运行时长:$HOURS 小时 $MINUTES 分钟" else echo "电池未处于放电状态,无法计算剩余运行时长" fi
注意事项
- 部分老款电池可能用
charge_now(安时)和current_now(安培)来计量,计算逻辑是一样的:charge_now / current_now得到小时数。 - 如果要做更精准的计算,可以每隔2-3秒读取一次
power_now,取平均值,避免瞬时功耗波动导致结果偏差。
二、计算充电时的充满时长
同样依赖sysfs的文件,额外需要energy_full(满电总电量,单位:μWh)。
计算逻辑
当电池处于Charging状态时,充满所需时长 = (满电总电量 - 当前剩余电量) / 当前充电功率,结果为小时数。
Bash示例代码
BAT_PATH="/sys/class/power_supply/BAT0" STATUS=$(cat "$BAT_PATH/status") if [ "$STATUS" = "Charging" ]; then ENERGY_FULL=$(cat "$BAT_PATH/energy_full") ENERGY_NOW=$(cat "$BAT_PATH/energy_now") POWER_NOW=$(cat "$BAT_PATH/power_now") if [ "$POWER_NOW" -eq 0 ]; then echo "当前充电功率为0,无法计算充满时长" exit 1 fi # 计算剩余需充入电量 CHARGE_REMAIN=$((ENERGY_FULL - ENERGY_NOW)) # 计算充电时长 CHARGE_TIME_HOURS=$(echo "scale=2; $CHARGE_REMAIN / $POWER_NOW" | bc) HOURS=$(echo "$CHARGE_TIME_HOURS" | cut -d. -f1) MINUTES=$(echo "scale=0; ($CHARGE_TIME_HOURS - $HOURS) * 60" | bc) echo "预计充满时长:$HOURS 小时 $MINUTES 分钟" else echo "电池未处于充电状态,无法计算充满时长" fi
注意事项
- 当电池接近满电时,大部分笔记本会自动降低充电功率来保护电池,所以这个计算是基于当前实时功率的估计值,实际充满时间可能会略长。
- 可以加入循环读取功率的逻辑,动态更新预计时长,让结果更准确。
如果你用C/C++开发命令行工具
这里给个简单的C语言片段,直接读取sysfs文件并计算:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BAT_BASE_PATH "/sys/class/power_supply/BAT0/" // 读取sysfs中的数值型文件 long long read_sysfs_value(const char *filename) { char full_path[100]; snprintf(full_path, sizeof(full_path), "%s%s", BAT_BASE_PATH, filename); FILE *file = fopen(full_path, "r"); if (!file) { perror("无法打开文件"); return -1; } long long value; fscanf(file, "%lld", &value); fclose(file); return value; } int main() { // 读取电池状态 char status[20]; FILE *status_file = fopen(BAT_BASE_PATH "status", "r"); if (!status_file) { perror("无法读取电池状态"); return 1; } fscanf(status_file, "%s", status); fclose(status_file); if (strcmp(status, "Discharging") == 0) { long long energy_now = read_sysfs_value("energy_now"); long long power_now = read_sysfs_value("power_now"); if (energy_now == -1 || power_now == -1 || power_now == 0) { printf("无法计算剩余运行时长:数据无效\n"); return 1; } double runtime = (double)energy_now / power_now; int hours = (int)runtime; int minutes = (int)((runtime - hours) * 60); printf("预计剩余运行时长:%d小时%d分钟\n", hours, minutes); } else if (strcmp(status, "Charging") == 0) { long long energy_full = read_sysfs_value("energy_full"); long long energy_now = read_sysfs_value("energy_now"); long long power_now = read_sysfs_value("power_now"); if (energy_full == -1 || energy_now == -1 || power_now == -1 || power_now == 0) { printf("无法计算充满时长:数据无效\n"); return 1; } double charge_time = (double)(energy_full - energy_now) / power_now; int hours = (int)charge_time; int minutes = (int)((charge_time - hours) * 60); printf("预计充满时长:%d小时%d分钟\n", hours, minutes); } else { printf("电池当前处于%s状态,无法计算目标时长\n", status); } return 0; }
最后补充
Arch Linux默认启用sysfs的power_supply接口,不需要安装任何额外包,这个方案是最轻量化、最可靠的。如果要兼容不同笔记本,可以遍历/sys/class/power_supply/目录下的所有子目录,筛选出以BAT开头的路径,自动适配多电池场景。
备注:内容来源于stack exchange,提问作者Ashish Kushwaha
相关产品推荐
相关产品推荐

