【问题标题】:How to daemonize non-privileged script in OSX Yosemite 10.10.3+如何在 OSX Yosemite 10.10.3+ 中守护非特权脚本
【发布时间】:2015-04-21 17:33:00
【问题描述】:

多年来,我们一直将流程监控/控制脚本作为我们应用程序的一部分。脚本的默认行为是守护自己。通常,脚本是由非特权用户启动的。由于我不会详细说明的原因,我们需要保留脚本和此行为。

OSX 系统上,我们通常通过 Apple 提供的 /usr/libexec/StartupItemContext 启动脚本让脚本在后台自行重启。这将我们的进程置于 Mach StartupItem 引导上下文而不是登录引导上下文中。这是必要的,因为如果没有上下文切换,如果用户注销时(这通常也是必要的),脚本将失去对目录服务、getpwuid()、DNS 服务等的访问权限。守护脚本的原始内部行基本上看起来像这样(在 perl 中):

my $cmd = "/usr/libexec/StartupItemContext myscript @Commandline > logs/startup 2>&1" ;         
system( "$cmd &") ;
exit 0 ;

OSX Yosemite出来后,那个StartupItemContext脚本消失了,所以我们切换到直接调用launchctl

my $cmd = "/usr/launchctl bsexec / myscript @Commandline > logs/startup 2>&1" ;         
system( "$cmd &") ;
exit 0 ;

然而,随着最近的 OSX 10.10.3 升级,launchctlbsexec 子命令突然需要 root 权限:

% launchctl bsexec
This subcommand requires root privileges: bsexec
% 

这给我们带来了一个令人瞩目的问题,即非特权用户无法再让我们的监控/控制脚本自行守护进程。

似乎Glassfish has encountered this problem 并用a patch 代替了

/bin/launchctl bsexec /

nohup

这可能适用于 Glassfish 实施,但我认为不适用于我们。尽管我不明白这一点——即为什么简单地阻止 SIGHUP 会阻止已停用的登录引导上下文中的进程丢失服务——但它似乎也不适用于我们需要的所有系统服务的测试.

什么是在 OSX 上从非特权的 Mach“登录”引导上下文开始守护进程的新规范方法,而不会失去对关键系统服务(如 DNS 等)的访问权限。用户退出?

【问题讨论】:

    标签: macos daemon osx-yosemite launchd mach


    【解决方案1】:

    “来自非特权的马赫“登录”引导上下文”不幸的是,不太可能有“规范的方式”。唯一规范的方法是通过 launchd 按需启动服务。甚至几乎不支持“bsexec”,也几乎没有文档记录。以我的经验,不可能跟上 OS X 的变化并且从不重新设计您的启动系统。我重新设计了所有其他版本的守护程序系统,因为 Apple 破坏了它,而且他们将继续破坏它。唯一的答案是继续努力使您的要求更简单。但几乎任何想要一直运行而不是按需运行的进程都直接违反了 Apple 的声明意图,因此它往往会中断。

    Apple 给出的解决方案是创建一个 LaunchDaemon 并在您的launchd plist 中为其分配一个UserName。您必须以特权启动,然后切换到用户(并且它需要是固定用户,而不是“登录用户”,因为那将是 LaunchAgent)。您无法通过这种方式升级您的访问权限。您不能将自己守护进程(同样,规范的答案是:不要那样做。请参阅 launchd.plist 手册页。)

    我怀疑 Glassfish nohup 解决方案只是一种躲闪,实际上并未将它们置于马赫上下文中。他们只是想避免在父 shell 退出时被杀死。那可能对你没有帮助。

    根据我的经验,最强大的解决方案是多部分的。您最终得到一个作为系统 LaunchDaemon(使用 KeepAlive)运行的部分,以及另一个作为用户 LaunchAgent 的部分,您让它们通过 IPC 进行通信,以便您可以访问您需要执行的每个活动所需的上下文.是的,这通常实现起来要复杂得多。更简单的解决方案往往行不通。

    当然,你必须不断地问自己“有没有任何方法可以让我按照 Apple 想要的方式做事来实现这一目标。”这意味着 XPC 是首选,其次是按需 LaunchDaemons 和 LaunchAgents。如果您构建您的系统以使用 XPC 组件,您可能会在更多的 OS X 升级中幸存下来。您发现不使用这些部件的任何工作都可能需要在 10.11 中再次修复。

    【讨论】:

    • 非常感谢@Rob 提供了有关如何重新设计它的知情草图。为了留出余地来追求这一点,除了打破要求的 sudo 之外,您是否知道我们即将到来的(一周)发布截止日期的任何短期躲避?例如old technical notes 建议除了“登录”上下文之外还有一个“用户”引导上下文。有没有办法启动一个进程,使其进入“用户”而不是“登录”上下文,从而有望在会话注销中幸存下来?我们对 Apple 的变化感到措手不及,谢谢
    • TN 就是你想要的地图。我总是回到它。我相信您正在查看的是非 GUI LaunchAgent。我不认为那些会在注销后幸存下来。当用户离开时,任何“每个用户”都会想要停止。您当然可以通过在 /Library/LaunchAgents 中放置一个 plist 来尝试它。您可以尝试分叉并与您的父级分离(可能需要 setsid 或双分叉)。这可能会保护您免于注销。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 2015-05-26
    • 2010-10-06
    • 2015-11-12
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    相关资源
    最近更新 更多