为所有具有GUI会话的用户启动/停止启动的代理 [英] Starting/stopping a launchd agent for all users with GUI sessions

查看:115
本文介绍了为所有具有GUI会话的用户启动/停止启动的代理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要能够从根级守护程序启动/停止每个会话的GUI代理.

I need to be able to start/stop a per-session GUI agent from a root level daemon.

此处此处此处.

我想做的基本上是

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保留下来,那么我会得到

but this only starts/stops one instance and it runs as root in the current GUI session. If I leave the sudo off there start I get

task_for_pid() (os/kern) failure
Couldn't switch to new bootstrap port: (ipc/send) invalid port right

我试图弄乱bsexec的其他多种排列方式(包括使用load/unload命令从bsexec调用辅助脚本),但是我永远无法让实例以root身份启动,并且永远不会另一个GUI会话.

I've tried messing around with a variety of other permutations of bsexec (including calling a secondary script from bsexec with the load/unload command), but I can never get the instance to start as anything other than root and never in another GUI session.

我也尝试过弄混su - <user> ...sudo -u <user> ...,但是那里也没有运气(正如以上链接的文章和其他地方所讨论的那样).

I also tried messing around with su - <user> ... and sudo -u <user> ..., but had no luck there either (as many people have discussed in the above linked articles and elsewhere).

有人有什么想法吗?

我尝试按照以下Graham Lee的建议使用包装器工具执行此操作,但出现以下错误:

I tried doing this with a wrapper tool as suggested below by Graham Lee, but I get the following error:

launch_msg(): Socket is not connected

这是我正在使用的命令行命令,包装程序和脚本(501是用户ID,63093是另一名登录到系统的用户启动的pid):

This is the command line command, wrapper, and script I'm using (501 is the userid and 63093 the pid of launchd for another user logged in to the system):

命令行:

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

推荐答案

使用launchctl bsexec是正确的,但是在运行真实"代理可执行文件之前,您需要启动一个包装器工具,该工具将UID丢弃给目标用户.哦,寻找loginwindow进程可能更好,因为这些进程是登录会话的负责人(尽管launchd也很有可能也可以工作).

Using launchctl bsexec is correct, but you need to launch a wrapper tool which drops UID to the target user before running the 'real' agent executable. Oh, and it's probably better to look for loginwindow processes, as those are the leaders of the login sessions (though launchd is very likely to work too).

这篇关于为所有具有GUI会话的用户启动/停止启动的代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆