首页 > 解决方案 > 根据电池状态、时间、百分比在 shell 提示中动态使用颜色

问题描述

我正在尝试创建一个动态提示,该提示使用颜色编码来提供电池情况的视觉提示。

我将pmset -g batt用来获取所有这些信息。

到目前为止,我正在处理

  1. 电池百分比
  2. 电池充电、放电、充电状态
  3. 电池预计充电或放电时间(=剩余时间

数字 1 可以通过 获取pmset -g batt | egrep '([0-9]+\%).*' -o --colour=auto | cut -f1 -d';',结果将是100%(嗯,目前,因为我的电池已充满电)。

数字 2 可以通过 获取pmset -g batt | awk '/charging|discharging|charged/ {print $4}' | cut -f1 -d';',但要使其在提示符中正常工作,您必须将其修改为pmset -g batt | awk '/charging|discharging|charged/ {print $4}' | cut -f2 -d';'- 然后在单词前显示一个尴尬的空格。所以" charged"代替"charged"," discharging"代替"discharging"" charging"代替"charging". 这很好,我想,但我认为这可以更进一步。

3 号可以通过pmset -g batt | grep -Eo '([0-9][0-9]|[0-9]):[0-5][0-9]'- 但是,如果你的电池充满电,你会得到一个很酷的0:00,这是没有意义的。

好的,我们已经确定这种信息是可以提取出来的,并且至少可以在终端本身显示出来,那么动态提示问题呢?


好吧,这就是我现在所拥有的:

[100%] [] [ charged] [Sat Nov 10 21:24:34] [~] >>

这并不完美。例如,[]根本不需要显示,考虑到它将显示的信息是0:00. 这[ charged]也有点不必要。

所以这就是我建议询问如何做的事情:

  1. 当电池充满时,只显示百分比,没有“ [time left / time to charge]”和“没有”[ charged]
  2. 当电池放电时,显示百分比,以及“ [time left](百分比颜色可以..修改?)。
  3. 电池充电时,显示百分比和“ [time left](百分比可能为黄色)。
  4. 当电池处于临界状态时(例如 15%)(百分比可能为红色)

现在,我做到了这一点:

export PS1="[\$(pmset -g batt | egrep '([0-9]+\%).*' -o --colour=auto | cut -f1 -d';')] [\$(pmset -g batt | grep -Eo '([0-9][0-9]|[0-9]):[0-5][0-9]')] [\$(pmset -g batt | awk '/charging|discharging|charged/ {print $4}' | cut -f2 -d';')] [\d \t]"

这给了我[100%] [0:00] [ charged] [Sat Nov 10 21:32:38]

无论如何,回到终端和提示之间的奇怪cut -f1cut -f2差异。如果我cut -f1输入export PS1提示,我会得到:

[100%] [0:00] [ -InternalBattery-0 (id=4194403) 100%] [Sat Nov 10 21:34:44]

无论如何,我认为必须有一种方法可以“哦,0:00?根本不显示提示的这一部分” - 但我不知道该怎么做。

所以,回顾一下,我正在尝试使用“充电、充电、放电”来设置电池百分比颜色,充电 = 常规颜色,充电 = 黄色,放电 = ..green?,小于 20% = 恐慌红色。5% 眨眼?:D

我还尝试使用“剩余充电时间”和“剩余充电时间”时间动态显示在提示本身中。

任何建议将不胜感激。

ps 如果在充电剩余时间内出现pmset -g batt结果,则显示 [估计] 的额外奖励积分(no estimate)

pps 额外奖励积分#2 用于弄清楚如何处理(即,这是一种不会(no estimate)但有时会发生的状态。

Now drawing from 'AC Power' -InternalBattery-0 (id=4194403) 89%; AC attached; not charging present: true

标签: bashmacosawkterminalprompt

解决方案


您的问题实际上是关于如何处理复杂的提示。 这里真正复杂的问题是如何在提示中处理有条件地使用 ANSI 颜色。

子问题是“正常”字符串压缩、条件和 ANSI 代码。所有这些我都在我的 dotfiles中处理,在profilefunctions_colors.sh.

你真正想要的是

export PS1="[\$(__batt_pct)]\$(__batt_time) [\$(__batt_state)] [\d \t] "

接着

yellow=$(tput setaf 184)
green=$(tput setaf 120)
red=$(tput setaf 160)
reset=$(tput init)

function __batt_pct() {
  bpct=$(pmset -g batt | egrep '([0-9]+)%.*' -o | cut -f1 -d';')
  bpct=${bpct%?} # remove last char (%)
  case 1 in
    $(($bpct <= 15))) echo "$red$bpct%$reset" ;;
    $(($bpct <= 65))) echo "$yellow$bpct%$reset" ;;
                   *) echo "$green$bpct%$reset" ;;
  esac
}

# now, as a function, we can easily handle a conditional
function __batt_time() {
  btime=$(pmset -g batt | grep -Eo '([0-9][0-9]|[0-9]):[0-5][0-9]')
  if [[ "$btime" == "0:00" ]]; then echo ''; else echo " [$btime]"; fi
}

# I need to cut field-1 for this to trim evenly
function __batt_state() {
  bstate=$(pmset -g batt | awk '/charging|discharging|charged/ {print $4}' | cut -f1 -d';')
}

我们使用__because 来遵循 unix 函数名的约定,不需要在 CLI 中手动使用。

对于颜色,只需遵循任何 ANSI 颜色指南,例如我在我的点文件中链接的那些。然后更改该__batt_state功能

# I need to cut field-1 for this to trim evenly
function __batt_state() {
  bstate=$(pmset -g batt | awk '/charging|discharging|charged/ {print $4}' | cut -f1 -d';')
  case "$bstate" in
    charged)
      echo "$green$bstate$reset"
      ;;
    charging)
      echo "$yellow$bstate$reset"
      ;;
    discharging)
      echo "$red$bstate$reset"
      ;;
    *)
      echo $bstate
      exit
  esac
}

我决定将所有这些都放在一个 repo中,以便我可以更轻松地使用它。


推荐阅读