1

我正在尝试设置一个在 OSX 上.plist使用的文件。launchctl从命令行(不使用launchctl)运行时,我们的应用程序执行如下:

/path/to/ourapp

...并终止我们的应用程序,我们输入:

/path/to/ourapp -k

...这会导致新实例ourapp正确杀死正在运行的前一个实例。

现在我设置了一个.plist文件来控制应用程序的执行launchctl,如下:

// start.plist
<dict>
    <key>Disabled</key>
        <false/>
    <key>Label</key>
        <string>ourapp</string>
    <key>ProgramArguments</key>
        <array>
            <string>/path/to/ourapp</string>
        </array>
    <key>OnDemand</key>
        <false/>
    <key>UserName</key>
        <string>daniel347x</string>
    <key>SHAuthorizationRight</key>
        <string>system.preferences</string>
</dict>

...我在命令行执行它,如下所示:

launchctl load /path/to/start.plist

这成功地启动了应用程序。

不幸的是,在创建 a 时stop.plist,如下所示(唯一的区别是添加了-k参数):

// stop.plist
<dict>
    <key>Disabled</key>
        <false/>
    <key>Label</key>
        <string>ourapp</string>
    <key>ProgramArguments</key>
        <array>
            <string>/path/to/ourapp</string>
            <string>-k</string>  // <-- only difference is adding this argument
        </array>
    <key>OnDemand</key>
        <false/>
    <key>UserName</key>
        <string>daniel347x</string>
    <key>SHAuthorizationRight</key>
        <string>system.preferences</string>
</dict>

...并通过执行

launchctl unload /path/to/stop.plist

...应用程序不会终止...因此,似乎在使用时launchctl,应用程序没有被等效地执行

/path/to/ourapp -k

有人能告诉我launchctl unload真正在做什么吗——即它是否使用给定的参数从命令行调用应用程序——以及stop.plist在使用时我能做些什么来让我工作launchctl unload,无论它在做什么?

4

1 回答 1

4

高水平

不,OSX 上的“launchctl unload”不会将“ProgramArguments”传递给目标应用程序。它从正在运行的那些中删除 plist。

简短的回答

我不确定您是否正在使用 launchctl 并按照设计方式启动,但请尝试:

launchctl load /path/to/stop.plist

更长的答案

launchctl 命令用于控制在任何给定时间运行哪些 plistslaunchd。当您发出:

launchctl load /path/to/start.plist

plist 被加载到launchd 中并且你的“ourapp”被触发。一个关键点是除非“ourapp”卸载start.plist,否则它仍然会在launchd中运行。您可以通过查看以下输出来检查:

launchctl list

您卸载 stop.plist 的调用没有任何效果的原因是它从未加载到 launchd 开始。为了能够停止它,您必须首先启动它:

launchctl load /path/to/stop.plist

这样做的诀窍是,一旦你这样做了,你的 start.plist 和 stop.plist 都会运行。显然,我尚未测试您的应用程序/设置,但这可能会导致奇怪的行为。另外,我不确定在 start.plist 上再次运行“加载”会做什么,因为它已经在运行。

形成您在此处描述的内容,看起来 launchd 和 launchctl 可能不是最好的方法。如果你想坚持下去,我认为你需要将系统调用添加到你的“ourapp”中,这样​​当它发出 kill 命令时,它也会卸载启动和停止 plist。或者,编写一个代理脚本来卸载 plist,然后调用您的“ourapp -k”。这样,下次您使用“launchctl load /path/to/start.plist”时,您将不会尝试启动已经在运行的东西。


另一个注意事项。您可能刚刚使用“ourapp”作为占位符,但值得指出的是,您可能希望使用唯一的标签名称。如果不出意外,它将帮助您使用“launchctl list”跟踪它们。我不知道 launchd 本身是否会出现重复名称的问题,但避免这种可能性似乎是最安全的。

于 2011-07-31T02:57:10.033 回答