我需要能够从根级守护进程启动/停止每个会话的 GUI 代理。
我想要能够做的基本上是
for num in `ps ax | grep [s]bin/launchd | cut -c 1-5`;
do
if [ $num -ne 1 ];
then
sudo launchctl bsexec $num launchctl (un)load -S Aqua /Library/LaunchAgents/com.mycompany.mydaemon.plist;
fi;
done
但这只会启动/停止一个实例,并在当前 GUI 会话中以 root 身份运行。如果我离开 sudo 那里开始我得到
task_for_pid() (os/kern) failure
Couldn't switch to new bootstrap port: (ipc/send) invalid port right
我尝试过处理 bsexec 的各种其他排列(包括使用 load/unload 命令从 bsexec 调用辅助脚本),但我永远无法让实例以 root 以外的任何方式启动,也永远无法在另一个 GUI 会话中启动.
我也尝试过使用su - <user> ...
and sudo -u <user> ...
,但也没有运气(正如许多人在上面链接的文章和其他地方所讨论的那样)。
有人有什么想法吗?
编辑:我尝试使用 Graham Lee 下面建议的包装工具执行此操作,但出现以下错误:
launch_msg(): Socket is not connected
这是我正在使用的命令行命令、包装器和脚本(501 是用户 ID,63093 是另一个登录到系统的用户的启动 pid):
命令行:
sudo launchctl bsexec 63093 /path/TestSetUIDAndExecuteTool 501 /path/LoadBillingDialogAgent
包装:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
if (argc != 3) {
NSLog(@"Tool called with improper arguments");
return -1;
}
int uid = [[NSString stringWithUTF8String:argv[1]] intValue];
// TODO: REMOVE
NSLog(@"Setting uid to |%i|", uid);
setuid(uid);
// TODO: REMOVE
char *command = (char *)argv[2];
NSLog(@"Executing command |%s|", command);
system(command);
[pool drain];
return 0;
}
脚本:
/bin/launchctl load -S Aqua /Library/LaunchAgents/com.company.agent.plist