启动/停止的launchd代理与GUI会话的所有用户(Starting/stopping a lau

2019-06-25 13:23发布

我需要能够启动/从根级守护停止在每个会话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会话根。 如果我离开须藤过​​那里开始,我得到

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

我试着瞎搞与各种bsexec的其他排列(包括bsexec调用次级脚本加载/卸载命令),但我永远不能获得实例开始作为根用户以外,从来没有在其他GUI会话什么。

我也试图与乱搞su - <user> ...sudo -u <user> ... ,但没有运气有两种(如很多人在上面链接的文章和其他地方的讨论)。

没有任何人有什么想法?

编辑:我试着用如Graham李以下建议的包装工具这样做,但我得到以下错误:

launch_msg(): Socket is not connected

这是命令行命令,包装和脚本我使用(501是用户标识和63093的launchd用于登录到系统中的另一个用户的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

Answer 1:

使用launchctl bsexec是正确的,但你需要启动的包装工具,它下降UID目标用户运行“真正的”代理可执行文件之前。 哦,它可能更好地寻找loginwindow过程,这些都是登录会话的领导者(尽管launchd很可能工作过)。



Answer 2:

它看起来像每个用户的launchd实例在同一引导命名空间launchctl从终端启动不运行。

通过使用Dock.app作为PID供体和一些神奇的须藤:

ps aux | grep Dock.app | grep -v grep | awk '{system("sudo launchctl bsexec "$2" sudo -u "$1" launchctl load -S Aqua /Library/LaunchAgents/com.my.agent.plist")}'

它可以在所有运行的会话发起代理。

不利落,但作品。

更新:无法在10.7工作。 是的,代理人将陆续推出,但我可以从测试中不正确的上下文看。



Answer 3:

基于这里的讨论, 这个剧本 ,我没有想到的包装工具应该是必要的。 这两个的bash脚本可以帮助别人了。

卸载代理

#!/bin/bash
for id in `ps aux | grep -v grep | grep MyAgent | awk {'print $2'}`
do
    launchctl bsexec $id launchctl unload /Library/LaunchAgents/myAgent.plist
done

与启动代理程序的名称替换“MyAgent”。

加载代理

#!/bin/bash
for pid_uid in $(ps -axo pid,uid,args | grep -i "[l]oginwindow.app" | awk '{print $1 "," $2}'); do

    pid=$(echo $pid_uid | cut -d, -f1)
    uid=$(echo $pid_uid | cut -d, -f2)

    launchctl bsexec "$pid" chroot -u "$uid" / launchctl load /Library/LaunchAgents/myAgent.plist
done

从根守护程序调用,这将加载和卸载启动代理在myAgent.plist引用的所有登录的用户。

需要注意的是,由于在OS X埃尔卡皮坦(10.11)“无根”,使用bsexec可能不再工作,但高达10.10,这应该是罚款。



Answer 4:

我有同样的问题。 为了解决这个问题,用“名为” launchd,即launchd会已经启动的进程的PID PID。

您承诺“launchctl bsexec” pid是用来找到合适的引导。 如果您使用的launchd的PID(从用户上下文)比你在根的launchd引导工作。 如果您使用的PE。 Finder或用户的码头PID,你可以在这个“每用户”引导工作



文章来源: Starting/stopping a launchd agent for all users with GUI sessions