我的应用程序是在root下启动的,我需要能够使用NSTask和launchctl卸载进程 这是我做的代码:
NSPipe *pipe = [NSPipe pipe];
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/launchctl"];
[task setCurrentDirectoryPath:@"/"];
[task setStandardError:pipe];
NSLog(@"/bin/launchctl unload %@", plistAutostartLocation);
NSArray *arguments;
arguments = [NSArray arrayWithObjects: enableCommand, plistAutostartLocation, nil];
[task setArguments: arguments];
NSFileHandle * read = [pipe fileHandleForReading];
[task launch];
[task waitUntilExit];
如果需要卸载进程是在" root"下启动的。如果没有失败,它会成功卸载。 问题是如何运行" launchctl"在特定用户下(例如" myusername")?
编辑: 在终端,如果我想在特定用户下运行一些命令,我接下来做的很好:
su - myusername -c" ls / Users / myusername"
但是,当我尝试运行" launchctl"在特定用户下它失败了:
su - myusername -c" launchctl load /Library/LaunchAgents/com.google.keystone.agent.plist"
它说:"没有找到任何东西加载"
答案 0 :(得分:1)
您的上一个命令失败与引导名称空间有关,您试图在错误的引导程序命名空间中加载代理程序。系统正在创建两个不同的引导名称空间,摘自Apple documentation:
值得注意的是 GUI和非GUI每会话之间的区别 引导名称空间。 GUI每会话引导程序命名空间是 由GUI基础架构实例化(
loginwindow
和WindowServer
) 当用户通过GUI登录时。非GUI每会话引导程序 用户通过SSH登录时创建名称空间。虽然没有 这些命名空间,基于GUI的服务之间的根本区别, 像Dock一样,只在GUI每会话引导程序中注册自己 命名空间。
su
命令未在launchd
使用的同一个bootsrap命名空间中启动。
有两种方法可以运行一个命令,就像你想在正确的bootstrap命名空间中运行一样:
10.10及以上:使用launchctl asuser
。这将运行由指定的<myusername>
启动的任何命令。值得一提的是,您必须以root身份运行它,否则命令将失败。你的上一个命令应该像这样运行:
launchctl asuser <myusername> launchctl load "/Library/LaunchAgents/com.google.keystone.agent.plist"
10.10及以下(自10.11起,SIP阻止此方法):使用launchctl bsexec
。这需要一个进程id来检索正确的命名空间,在该命名空间中运行另一个命令。此外,您必须手动更改命令的UID,如下所示:
launctl bsexec <pid> su -u <myusername> launchctl load "/Library/LaunchAgents/com.google.keystone.agent.plist"