根据电池状态、时间、百分比在 shell 提示中动态使用颜色

Dynamically use colors in a shell prompt depending on battery state, time, percentage

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

我将使用 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 }' | cut -f1 -d';' 获取,但要使其在提示中正常工作,您必须将其修改为 pmset -g batt | awk '/charging|discharging|charged/ {print }' | cut -f2 -d';' - 然后会显示一个尴尬的空白 space字前。所以 " 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 }' | 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]

无论如何,我认为必须有一种方法 "oh, 0:00? don't display this segment of the prompt at all" - 但我不确定该怎么做。

所以,回顾一下,我正在尝试利用 "Charged,Charging,Discharging" 设置电池百分比颜色,充电 = 常规颜色,充电 = 黄色,放电 = ..绿色?,小于 20% = 恐慌红色。 5%眨眼? :D

我也在尝试使用 "time left to charge" 和 "time left of charge" 时间动态显示在提示本身中。

如有任何建议,我们将不胜感激。

p.s。如果 pmset -g batt 在充电剩余时间

导致 (no estimate),则显示 [估计] 的额外奖励积分

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

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

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

子问题是 'normal' string chomping、conditional 和 ANSI code。我在 profilefunctions_colors.sh 中处理所有这些 in my dotfiles

你真正想要的是

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 }' | cut -f1 -d';')
}

我们使用 __ 是因为要遵循函数名称的 unix 约定,不需要在 CLI 中手动使用。

对于颜色,只需 follow any ANSI color guide,例如我在我的点文件中链接的那些。然后更改 __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 }' | 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
}

I decided to drop all of this in a repo,方便我使用