Eri*_*cus 7 macos bash restart sh launchd
我正在尝试让脚本每天同时运行以重新启动 Mac。我无法使用节能首选项面板中的内置计划功能,因为我正在运行阻止正常重启的应用程序。如果我通过终端中的命令启动重新启动,shutdown它将强制重新启动,无论哪些应用程序可能会阻止它。
我对 shell 脚本和 launchd 非常陌生,所以我真的是一个新手级别,所以请记住这一点。这是我在这里发表的第一篇文章,但多年来我定期访问并通常找到我正在寻找的答案。
在尝试了各种事情之后,我遇到了一些障碍。我所在的位置是 /Library/LaunchDaemons 文件夹中有一个 .plist 文件,该文件指向应在特定时间运行的脚本。我最初尝试使用在线教程中找到的代码在 bbedit 中编写 .plist 文件。它总是无法加载到 launchctl (手动或通过重新启动)。然后我尝试使用 Xcode 中的 plist 编辑器,效果似乎更好。
完成此操作后,plist 将加载到 launchctl 中。它似乎还尝试在指定时间运行脚本。我查看了控制台,Mac 似乎确实尝试运行该脚本,但失败并出现以下错误:
com.apple.xpc.launchd[1] (com.apple.restart.sh[940]): 服务退出并出现异常代码: 1
我尝试直接从终端运行脚本,例如sh scriptname,Mac 重新启动。
这是脚本:
#!/bin/bash
shutdown -r now
我将脚本保存在 /Library/Scripts 文件夹中。
这是 .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>com.apple.restart.sh</string>
    <key>Program</key>
    <string>/Library/Scripts/com.apple.restart.sh</string>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>9</integer>
        <key>Minute</key>
        <integer>50</integer>
    </dict>
</dict>
</plist>
我现在真的不知道出了什么问题,因为 .plist 似乎已成功加载到 launchctl 中,并且脚本尝试在指定时间运行但失败了。如果手动运行该脚本,它就可以工作。
我最好的猜测是这与权限或所有权有关,但这只是我的直觉。我尝试过chown root:wheel在文件上运行。这将错误更改为:
异常代码78
任何帮助将不胜感激。
最新的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>com.erithacus.restart</string>
    <key>Program</key>
    <string>/Library/Scripts/com.erithacus.restart.sh</string>
    <key>StandardOutPath</key>
    <string>/tmp/com.erithacus.restart.stdout</string>
    <key>StandardErrorPath</key>
    <string>/tmp/com.erithacus.restart.stderr</string>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>11</integer>
        <key>Minute</key>
        <integer>10</integer>
    </dict>
</dict>
</plist>
最新脚本内容:
#!/bin/bash
/sbin/shutdown -r now >>/tmp/shutdown.log 2&>1
.stdout 文件的内容为空。
.stderr的内容如下:/Library/Scripts/com.erithacus.restart.sh: line 3: 1: Read-only file system
这是否与 macOS Catalina 的操作系统位于只读分区有关?
编辑2.一个解决方案。
最终的 plist 文件 (com.erithacus.restart.sh) 内容(但必须使用 Xcode 制作):
<?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>com.erithacus.restart</string>
    <key>Program</key>
    <string>/Library/Scripts/com.erithacus.restart.sh</string>
    <key>StandardOutPath</key>
    <string>/tmp/com.erithacus.restart.stdout</string>
    <key>StandardErrorPath</key>
    <string>/tmp/com.erithacus.restart.stderr</string>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>12</integer>
        <key>Minute</key>
        <integer>10</integer>
    </dict>
</dict>
</plist>
(显然改变下面的时间StartCalendarInterval以适应)
此 plist 保存在 /Library/LaunchDaemons 中
最终脚本(com.erithacus.restart.sh):
#!/bin/bash
date +"%F %T Shutting down"
/sbin/shutdown -r now
脚本保存在/Library/Scripts中
我认为与原始版本相比最关键的根本改变是我将 plist 文件的所有权更改为root使用sudo chown root [plist file name].
然后我必须将其加载为launchctlroot,即sudo launchctl load [plist file name]。奇怪的是,当以这种方式加载时,它不会显示在命令中launchctl list,但会显示 if sudo launchctl list。
这导致系统成功定时重新启动计算机,从而覆盖任何可能阻止重新启动的应用程序。这对于我想每天早上 5 点重新启动的服务器很有帮助(所以显然 plist 文件中的时间现在将更改为在那个时间运行)。
特别感谢@marksetcell,他的错误记录建议帮助我解决了这个问题。
有几件事需要检查。
首先,确保您的脚本可以执行:
chmod +x /Library/Scripts/com.apple.restart.sh
其次,将完整路径放入shutdown脚本中以确保可以找到它:
#!/bin/bash
/sbin/shutdown -r now
我发现通过运行:
which shutdown
输出
/sbin/shutdown
第三,确保您的脚本是纯 ASCII 文本,而不是 RTF、Pages或MS-Word文档:
file /Library/Scripts/com.apple.restart.sh
输出
/Library/Scripts/com.apple.restart.sh: Bourne-Again shell script text executable, ASCII text
第四,在外部测试您的脚本launchctl以确保它首先独立运行:
/Library/Scripts/com.apple.restart.sh
第五,在文件中像这样重定向输出plist:
<key>StandardOutPath</key>
<string>/tmp/com.apple.restart.stdout</string>
<key>StandardErrorPath</key>
<string>/tmp/com.apple.restart.stderr</string>
| 归档时间: | 
 | 
| 查看次数: | 12536 次 | 
| 最近记录: |