我认为您的脚本本身就是一个很好的脚本,但如果定期运行,最终可能会占用大量资源,因为它会调用一个 shell 进程和两个程序来获取您所需要的信息。
在这种情况下,我认为 AppleScript 具有 shell 脚本的几个优点,这在很大程度上要归功于 osascript,它是运行 AppleScript 时唯一需要执行的程序,并且无需创建外壳进程。
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>
使用与Label 键下的<string> 条目匹配的文件名保存它。在这种情况下,我将我的保存为local.battery.plist。我还将 AppleScript 保存在 plist 中指定的路径中。在我的实验中,我很惊讶launchd 不喜欢它,如果路径中有任何空格(即使转义),或者如果我使用波浪号 (~) 作为我的主目录的简写。因此,我将 AppleScript 保存为简单的 Battery.applescript,并提供了我放置它的完整路径。
StartInterval 是您可以指定脚本运行的时间间隔(以秒为单位)的地方。就个人而言,我认为 60 秒有点过大,但我将其设置为测试。在实践中,我可能会选择将其设置为 600(10 分钟),但您可以判断什么最适合您。
最后的两个/tmp/ 路径分别是错误和返回值的写入位置。如果您更改日志文件的路径,请不要忘记更新 AppleScript 中的 file 属性。
保存或移动 plist 到目录~/Library/LaunchAgents/。
-
从终端使用以下 shell 命令加载它:
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
结束思想
第一次电池信息很有趣,但对于大多数用例来说可能是多余的。 (也就是说,我刚刚注意到它建议我在BatteryHealth 下使用"Check Battery",所以我现在很高兴我提取了额外的数据。
无论如何,如果您认为自己不需要额外的数据,我已经看到user3439894 留下的评论,它提供了一种非常好的、紧凑且简单的方法来检索有关电池的更重要信息,即它的百分比水平以及它是否在收费。可以说,这可能是比我的 ObjC 方法更合适的 AppleScripting 解决方案,后者会带来 small 开销,而且脚本更短。
目前,我坚持使用我的,因为我显然有电池健康问题,应该可以得到解决。