如果这是一个交互式程序,那么使用authopen 将是完美的,否则我会使用launchd。
我刚刚注意到这个答案已被删除。为什么有人会删除正确的答案?
这里有一个简化的例子来说明使用 authopen 来回答问题:
package macos4;
import java.io.File;
import java.io.IOException;
public class MacOS4 {
public static void main(String[] args) throws IOException, InterruptedException {
String destinationFileName = "/Library/Application Support/tempFile/";
ProcessBuilder builder = new ProcessBuilder("/usr/libexec/authopen", "-c", "-w", "-a", destinationFileName);
builder.redirectInput(new File("src/resources", "input.txt"));
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
Process process = builder.start();
process.waitFor();
process.destroy();
}
}
如果 tempFile 不存在,这将创建它,并将资源包中 input.txt 的内容写入其中。它将弹出进行身份验证:
这意味着不需要将密码传递给子进程。
有关需要防止外部进程阻塞 IO 缓冲区的非常重要的注意事项,请参阅this。
如果您希望自己的工作无人看管怎么办?是时候启动了,但请记住,整个程序将以 root 身份运行,这与我在上面发布的交互式选项不同,其中只有文件操作以 root 身份运行。我写了这个简单的程序,我想每 5 分钟运行一次。每次运行时,它都会在“/Library/Application Support/tempFile”中添加一行当前日期和时间;每 30 分钟它会覆盖文件并重新开始,但只保留最后一个时间戳。这是程序:
package maclaunchd;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.FileTime;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MacLaunchd {
public static void main(String[] args) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date date = new Date();
File tempFile = new File("/Library/Application Support/tempFile");
if (!tempFile.exists()) {
tempFile.createNewFile();
}
FileTime creationTime = (FileTime) Files.getAttribute(tempFile.toPath(), "creationTime");
boolean append = (System.currentTimeMillis() - creationTime.toMillis() <= 1800000);
FileWriter fw = new FileWriter(tempFile, append);
try (BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(sdf.format(date) + "\n");
}
} catch (IOException ex) {
Logger.getLogger(MacLaunchd.class.getName()).log(Level.SEVERE, null, ex);
throw new RuntimeException(ex);
}
}
}
然后我创建了一个名为“maclaunchd.MacLaunchd.daemon.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>GroupName</key>
<string>wheel</string>
<key>KeepAlive</key>
<false/>
<key>Label</key>
<string>maclaunchd.MacLaunchd.daemon</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/java</string>
<string>-jar</string>
<string>/Users/enta/NetBeansProjects/MacLaunchd/dist/MacLaunchd.jar</string>
</array>
<key>RunAtLoad</key>
<false/>
<key>StandardErrorPath</key>
<string>/Users/enta/NetBeansProjects/MacLaunchd/dist/err.log</string>
<key>StandardOutPath</key>
<string>/Users/enta/NetBeansProjects/MacLaunchd/dist/out.log</string>
<key>StartInterval</key>
<integer>300</integer>
<key>UserName</key>
<string>root</string>
<key>WorkingDirectory</key>
<string>/Users/enta/NetBeansProjects/MacLaunchd/dist/</string>
</dict>
</plist>
接下来我将文件复制到正确的位置,加载并启动它:
sudo cp maclaunchd.MacLaunchd.daemon.plist /Library/LaunchDaemons
sudo launchctl load /Library/LaunchDaemons/maclaunchd.MacLaunchd.daemon.plist
sudo launchctl start maclaunchd.MacLaunchd.daemon
如果您 cat "/Library/Application Support/tempFile",您将看到每 5 分钟写入一次的日期。要停止、卸载和删除作业运行:
sudo launchctl stop maclaunchd.MacLaunchd.daemon
sudo launchctl unload /Library/LaunchDaemons/maclaunchd.MacLaunchd.daemon.plist
sudo rm /Library/LaunchDaemons/maclaunchd.MacLaunchd.daemon.plist
现在您有两个选项可以写入“/Library/Application Support/”。