有没有办法只在关机时运行脚本?
我的意思是,只有当计算机真正关闭到关闭状态时。仅在注销或重新启动时不应运行此脚本。
有没有办法只在关机时运行脚本?
我的意思是,只有当计算机真正关闭到关闭状态时。仅在注销或重新启动时不应运行此脚本。
几天前,我在 github 上发布了一个可以在 boot/shutdown 执行的配置/脚本。
基本上在 Mac OS X 上,您可以/应该将System wide and per-user daemon/agent configuration file
(plist)与 bash 脚本文件结合使用。这是您可以使用的 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>Label</key><string>boot.shutdown.script.name</string>
<key>ProgramArguments</key>
<array>
<string>SCRIPT_PATH/boot-shutdown.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>LOG_PATH/boot-shutdown.log</string>
<key>StandardErrorPath</key>
<string>LOG_PATH/boot-shutdown.err</string>
</dict>
</plist>
您可以将此文件放入/Library/LaunchDaemons
. 可以放置plist文件的目录有很多,这取决于你需要什么,进程的权限等等。
~/Library/LaunchAgents Per-user agents provided by the user.
/Library/LaunchAgents Per-user agents provided by the administrator.
/Library/LaunchDaemons System wide daemons provided by the administrator.
/System/Library/LaunchAgents Mac OS X Per-user agents.
/System/Library/LaunchDaemons Mac OS X System wide daemons.
该脚本boot-shutdown.sh
将在每次启动/关闭时加载和执行。
#!/bin/bash
function shutdown()
{
# INSERT HERE THE COMMAND YOU WANT EXECUTE AT SHUTDOWN OR SERVICE UNLOAD
exit 0
}
function startup()
{
# INSERT HERE THE COMMAND YOU WANT EXECUTE AT STARTUP OR SERVICE LOAD
tail -f /dev/null &
wait $!
}
trap shutdown SIGTERM
trap shutdown SIGKILL
startup;
然后调用launchctl
加载和卸载守护进程/代理的命令。
sudo launchctl load -w /Library/LaunchDaemons/boot-shutdown-script.plist
看起来最直接的方法是编写一个小型 C++ 应用程序,该应用程序将作为守护进程使用launchctl运行,捕获关闭通知但忽略重新启动通知(见下文),然后将提供给它的任何内容作为参数调用,例如外壳脚本。Apple 似乎没有提供库来捕捉任何其他语言的通知。
来自 Apple的“内核编程”手册https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/KernelProgramming/KernelProgramming.pdf ,第 150 页:
“虽然 OS X 没有传统的 BSD 风格的关闭钩子,但 I/O Kit 在最近的版本中提供了等效的功能。由于 I/O Kit 提供了此功能,因此您必须从 C++ 代码中调用它。”
“要注册通知,请调用 registerSleepWakeInterest(在 IOKit/RootDomain.h 中描述)并注册睡眠通知。如果系统即将关闭,则使用消息类型 kIOMessageSystemWillPowerOff 调用您的处理程序。如果系统即将关闭重新启动,您的处理程序将获得消息类型 kIOMessageSystemWillRestart。如果系统即将重新启动,您的处理程序将获得消息类型 kIOMessageSystemWillSleep。”
如您所见,有不同的重启消息,因此您可以专门处理关机情况。
这是一种可行的方法(我只是对其进行了测试),但它非常技术性,不适合没有经验的人......我在/sbin/shutdown 周围放置了一个包装器。即使您从 GUI 中的 Apple 菜单关闭 Mac,这也将起作用。
基本上,您需要su
像这样 root,并将现有的 Apple 提供的shutdown
二进制文件重命名为shutdown.orig
.
su -
cd /sbin
mv shutdown shutdown.orig
然后,您创建一个 bash 脚本shutdown
,该脚本首先执行您想要的操作,然后execs
是 Apple 提供的原始关闭二进制文件。
#!/bin/bash
Do something you want done before shutdown
exec /sbin/shutdown.orig "$@"
有三点需要注意...
1. Make all the permissions the same on shutdown as shutdown.orig
2. Parse the parameters to the originl shutdown and see if `-r` is one of them as this means it is a `restart` shutdown. You will also have to pass through the other parameters that Apple calls the script with - if any.
3. Apple may feel at liberty to overwrite your lovely, shiny, new `shutdown` script when updating OSX, so maybe abstract out the bulk of your personal shutdown script into another place so that you can easily re-insert a single-line call to it if/when Apple overwrites it at some point.
当心!并先做好备份!
万一有人像我一样在谷歌上搜索类似但有些不同的问题。
由于我发现https://github.com/hluk/CopyQ/issues/1301的 CopyQ 崩溃错误,我 不得不编写一个 cron 脚本,如果它崩溃,它将重新加载。但我不想重新加载 copyq,如果 copyq 在关机或重启期间退出
我最终使用
if ps aux | grep "Finder.app" | grep -v grep
then
echo "I am still running"
else
echo "I am in shutdown"
fi
要检测系统是否处于关闭状态,(您可以Chrome.app
根据需要使用或任何其他始终运行的应用程序)
不完全是解决方案,但帮助我解决了我遇到的类似问题