几年前,我整理了以下内容expect
执行 Open Directory 备份的脚本在 Tiger Server 下也能很好地运行,并且在 Leopard Server 下也能很好地运行:
#!/usr/bin/expect -f
set date [timestamp -format "%Y-%m-%d"]
set archive_path "path/to/you/backup/dir"
set archive_password "password"
set archive_name "opendirectory_backup"
spawn /usr/sbin/slapconfig -backupdb $archive_path/$archive_name-$date
expect "Enter archive password"
send "$archive_password\r"
expect eof
它是少数几个仍存在于 root crontab 中的脚本之一,而不是 plist 。出于明显的安全原因,launchd
它只能由 root 执行。rwx
现在,问题是几周前我将 Open Directory Master 升级到 Mac OS X 10.6.4 Snow Leopard Server,但从那以后,当通过 cron 运行时,它就一直无法正常工作。如果我以 root 用户身份登录并手动运行它,它会正常工作并创建生成的加密磁盘映像。当通过 cron 运行时,它会执行全部动作(包括与/Library/Logs/slapconfig.log
手动运行时的输出相匹配的输出),但永远不会创建磁盘映像文件。但是,在 `/var/log/system.log/ 中,我看到以下输出:
Jul 23 03:00:08 servername hdiejectd[93114]: running
Jul 23 03:00:11 servername diskimages-helper[93111]: -frameworkCallbackWithDictionary: threw exception calling home.
Jul 23 03:00:11 servername diskimages-helper[93111]: threw exception reporting results back to framework.
Jul 23 03:00:21 servername hdiejectd[93114]: quitCheck: calling exit(0)
手动运行时,输出如下(无diskimages-helper
例外):
Jul 23 14:29:27 servername hdiejectd[7776]: running
Jul 23 14:29:40 servername hdiejectd[7776]: quitCheck: calling exit(0)
在这两种情况下,都没有用户通过 GUI 登录。我有几个朋友在他们的 OD Master 上运行相同的脚本,而且自从升级到 Snow Leopard Server 后,该脚本也不再通过 cron 运行。
我记得 Mac OS X 的命令行磁盘映像工具存在一些问题,需要钥匙串访问,但我不记得具体细节了。与此相关的一些问题在 Snow Leopard Server 中是否变得更加严格了?
有什么想法或建议吗?
答案1
我在调试原始脚本时遇到了同样的问题,对我来说,默认的预期超时时间为 10 秒,导致嵌入的 hdiutil 命令中止。我通过添加以下内容解决了此问题:
设置超时 120
在期望脚本中。现在脚本又可以正常工作了。我的脚本:
#!/usr/bin/expect -f
set date [timestamp -format "%Y-%m-%d"]
set archive_path "path/to/you/backup/dir"
set archive_password "password"
set archive_name "opendirectory_backup"
set timeout 120
spawn /usr/sbin/slapconfig -backupdb $archive_path/$archive_name-$date
expect "Enter archive password"
send "$archive_password\r"
expect eof
答案2
好的,我现在有一个可行的解决方案。我首先编写了一个新bash
脚本(而不是使用expect
),该脚本包装了 Apple 的serveradmin
实用程序(它本身就是包装了slapconfig -backupdb
我一直直接从剧本expect
):
#!/bin/bash
dst="/path/to/your/backup/directory"
pass="password"
host=$(hostname)
date=$(date +%Y-%m-%d-%H%M)
serveradmin command <<-EOC
dirserv:backupArchiveParams:archivePassword = $pass
dirserv:backupArchiveParams:archivePath = ${dst}/od_backup-${host}-${date}
dirserv:command = backupArchive
EOC
它基于这个脚本,但使用“此处文档”而不是在磁盘上创建包含要运行的命令(包括纯文本密码)的bash
文件。serveradmin
这个在从命令行运行时也能正常工作,但从.sparseimage
cron 运行时仍然没有创建。因此,我的修复的第二阶段是,正如我在原始问题的评论中提到的那样,创建一个launchd
plist 来运行它:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
<key>Label</key>
<string>tld.domain.od_backup</string>
<key>ProgramArguments</key>
<array>
<string>/var/root/sbin/od_backup</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>2</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
</dict>
</plist>
当然,我加载了 plist sudo launchctl load /Library/LaunchDaemons/tld.domain.od_backup.plist
(更改了域和 tld 以保护身份)。而且,当通过 调用时,它似乎可以正确运行launchd
。如果通过 调用,原始脚本可能也可以正确运行launchd
,但我还没有测试过。