我正在使用 MacBook,但电池不可靠。我试图找到一个脚本命令,当电池电量低于阈值时,该命令将使笔记本电脑发出哔哔声。经过一些搜索和测试,我在下面找到了一个快速解决方案:
1)我首先创建一个名为 check_battery 的文件,内容如下:
ioreg -l | awk '$3~/Capacity/{c[$3]=$5}END{OFMT="%.3f";max=c["\"MaxCapacity\""]; bat= (max>0?100*c["\"CurrentCapacity\""]/max:"?"); printf("%d", bat)}'
2)然后我创建了以下文件:
\#!/bin/bash
sh check_battery>battery;
let t=60
read a < battery
if(( "$a" < "$t" ));
then
say "Battery level is lower than 60%!";
say "BEAP BEAP"
fi;
3)最后,我尝试将其添加到我的 crontab 作业中,但 crontab 已被 iOS 停止。然后我发现我必须使用launchd,具体如下:
https://alvinalexander.com/mac-os-x/mac-osx-startup-crontab-launchd-jobs
它现在在我的 MacBook 实验室中工作,但可能有更好的解决方案。如果您有其他解决方案,请与我分享。非常感谢。
最佳答案
我认为您的脚本本身就是一个很好的脚本,但在定期运行时最终可能会占用大量资源,因为它会调用一个 shell 进程和两个程序来获取您想要的信息。
在这种情况下,我认为 AppleScript 具有 shell 脚本的几个优点,这主要归功于 osascript
,这是唯一一个需要执行才能运行 AppleScript 的程序,它可以在不创建 shell 进程的情况下执行此操作。
用于检索电池信息的 AppleScript
这是一个这样的脚本,它可以检索有关计算机电池的信息,并在适当的时候发出警告:
property threshold : 20 -- The level below which the script issues warnings
property verbose : false -- Report current battery level on every run
property file : "/tmp/battery.log" -- The path to the log file (from plist)
set eof of my file to 0
tell the battery()
set warning_level to the warningLevel()
if the warning_level = 1 then return check()
warn about (warning_level - 1) * 5 with alert
end tell
# warn
# Sends out a visible and audible warning with information about the
# remaining charge (+level) on the battery. Invoke without alert to have
# the +level reported in the notification centre as a percentage. Invoke
# with alert to have the +level reported in a pop-up alert dialog as an
# estimation of the remaining battery time (in minutes), and which must be
# dismissed by the user.
to warn about level without alert
if not alert then display notification ¬
["Current battery level: ", level, "%"] as text ¬
with title ["⚠️ Battery Warning"] sound name "Basso"
say "Warning: battery low" using "Moira" pitch 127 ¬
speaking rate 180 without waiting until completion
if alert then display alert ["Warning: battery level is very low"] ¬
message ["Estimated time remaining: " & level & " minutes"] ¬
as critical giving up after 0
end warn
# battery()
# Contains a script object that defines a number of convenience handlers that
# retrieve information about the on-board power source
on battery()
script
use framework "IOKit"
use scripting additions
property warninglevels : ["None", "Early", "Final"]
on warningLevel() -- A ten-minute warning indicator
IOPSGetBatteryWarningLevel() of the current application
end warningLevel
on info()
IOPSCopyPowerSourcesInfo() of the current application ¬
as record
end info
to check()
copy [it, |current capacity|, |is charging|] of ¬
info() to [ps_info, percentage, charging]
if the percentage ≤ threshold ¬
and it is not charging ¬
then warn about percentage ¬
without alert
if verbose then return display notification [¬
"Percentage: ", percentage, linefeed, ¬
"Charging: ", charging] as text ¬
with title ["🔋 Battery Information"]
["Script last run on ", current date, linefeed, ¬
linefeed, __string(ps_info), linefeed] as text
end check
end script
end battery
# __string()
# A that will return an AppleScript record as a formatted string, modified
# specifically for use in this script, therefore may not port very well to
# handle other records from other scripts
to __string(obj)
if class of obj = text then return obj
try
set E to {_:obj} as text
on error E
my tid:{null, "Can’t make {_:", ¬
"} into type text.", ¬
"{", "}", "|"}
set E to E's text items as text
my tid:{linefeed, ", "}
set E to E's text items as text
end try
end __string
# tid:
# Set the text item delimiters
on tid:(d as list)
local d
if d = {} or d = {0} then set d to ""
set my text item delimiters to d
end tid:
它最显着地检索电池剩余电量的当前百分比以及电池当前是否正在充电。
您可以根据自己的喜好安全地更改脚本顶部的三个属性。在
verbose
模式,每次运行脚本时都会报告电池百分比和充电状态。如果您按分钟运行脚本,这可能会令人恼火,因此将其设置为 false
默认情况下。但是,当电池电量低于
threshold
时,您将收到通知中心的通知,以及 Moira 舒缓的苏格兰语气,它会发出声音警告,提示击球手电量不足。如果电池电量严重不足,您会收到一个弹出式警报,提示您必须亲自离开。
该脚本还会返回一堆有关电池的其他信息,一般来说,您不会看到这些信息。但是,如果脚本被
launchd
执行plist,返回的信息记录在日志文件中,您可以在闲暇时检查。launchd
launchd
提供了一种很好的、具有成本效益的定期运行脚本的方法,并且比创建 Stay Open 应用程序来轮询数据更可取(这是非常低效的,但在其他场景中也有用途)。您已经找到了一个很好的链接来描述有关编写
.plist
的基础知识。文件以及如何保存它,然后调用(启动)它。我将在这里总结要点:.plist
看起来像这样:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>local.battery</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/osascript</string>
<string>/Users/CK/Documents/Scripts/AppleScript/scripts/Battery.applescript</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>60</integer>
<key>StandardErrorPath</key>
<string>/tmp/battery.err</string>
<key>StandardOutPath</key>
<string>/tmp/battery.log</string>
</dict>
</plist>
使用与
<string>
匹配的文件名保存它Label
下的条目 key 。在这种情况下,我将我的保存为 local.battery.plist
.我还在 plist 中指定的路径中保存了我的 AppleScript。在我的实验中,我很惊讶 launchd
如果路径中有任何空格(即使已转义),或者如果我使用波浪号( ~
)作为主目录的简写,我就不喜欢它。因此,我将 AppleScript 保存为简单的 Battery.applescript
并提供了我放置它的完整路径。StartInterval
您可以在此处指定脚本运行的间隔(以秒为单位)。就个人而言,我认为 60 秒有点矫枉过正,但我将其设置为用于测试。在实践中,我可能会选择将其设置为 600(10 分钟)之类的值,但您可以判断什么最适合您。两人
/tmp/
最后的路径分别是写入错误和返回值的地方。如果更改日志文件的路径,请不要忘记更新 file
AppleScript 中的属性。 ~/Library/LaunchAgents/
. launchctl load ~/Library/LaunchAgents/local.battery.plist
.plist
进行了任何更改或 .applescript
,记得先卸载再用launchctl
重新加载:launchctl unload ~/Library/LaunchAgents/local.battery.plist
launchctl load ~/Library/LaunchAgents/local.battery.plist
成功加载
.plist
后进入 launchd
,它应该立即运行 AppleScript 并将返回的数据写入日志文件。这是我的 /tmp/battery.log
的输出文件:Script last run on Tuesday, 1 January 2019 at 22:01:52
is present:true
is charged:true
power source state:"AC Power"
Current:0
max capacity:100
DesignCycleCount:1000
current capacity:100
name:"InternalBattery-0"
battery provides time remaining:true
is charging:false
hardware serial number:"D8663230496GLLHBJ"
transport type:"Internal"
time to empty:0
power source id:4391011
Type:"InternalBattery"
BatteryHealth:"Check Battery"
time to full charge:0
闭幕式
第一次电池信息非常有趣,但对于大多数用例来说可能是多余的。 (也就是说,我已经 只有 注意到有人建议我在
"Check Battery"
下 BatteryHealth
,所以我现在很高兴我提取了额外的数据)。无论如何,如果额外的数据不是你认为自己需要的东西,我已经看到了 user3439894 留下的评论。这提供了一种非常好的、紧凑的和简单的方法来检索有关电池的更显着信息,即它的百分比水平以及它是否正在充电。这可以说是比我的 ObjC 方法更合适的 AppleScripting 解决方案,它会带来很小的开销,而且可以制作更短的脚本。
现在,我坚持我的,因为我显然有电池健康问题,可能应该解决这个问题。
关于bash - 在 MacOS 中,当电池电量低于阈值时播放警告的脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53997451/