我需要能够从根级别守护程序启动/停止每会话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> ...
和sudo -u <user> ...
,但也没有运气(很多人在上面的链接文章和其他地方讨论过)。
有人有任何想法吗?
编辑: 我尝试使用Graham Lee下面建议的包装工具执行此操作,但是我收到以下错误:
launch_msg(): Socket is not connected
这是我正在使用的命令行命令,包装器和脚本(501是用户ID,63093是另一个登录到系统的用户的launch的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
答案 0 :(得分:6)
使用launchctl bsexec
是正确的,但您需要启动一个包装工具,在运行“真正的”代理可执行文件之前将UID丢弃给目标用户。哦,最好寻找loginwindow
进程,因为那些是登录会话的领导者(尽管launchd
很可能也会工作)。
答案 1 :(得分:4)
看起来每个用户启动的实例与从终端启动的launchctl不在同一个引导程序命名空间中运行。
使用Dock.app作为pid捐赠者和一些sudo魔法:
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。是的,代理将会启动,但正如我在测试中看到的那样,不是在正确的背景下。
答案 2 :(得分:3)
根据此处的讨论和this script,我并不认为应该使用包装工具。这两个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&#39;使用启动代理的名称。
加载代理商
#!/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中为所有登录用户引用的启动代理。
请注意,由于“无根”&#39;在OS X El Capitan(10.11)中,bsexec的使用可能不再有效,但高达10.10,这应该没问题。
答案 3 :(得分:1)
我遇到了同样的问题。 要解决这个问题,请在&#34;下使用pid&#34; launchd,启动进程的pid已经开始。
你承诺的pid&quot; launchctl bsexec&#39;用于找到正确的引导程序。如果你使用launchd的pid(来自用户上下文)而不是你在root launchd bootstrap中的工作。如果你使用pe。用户的Finder或Dock pid,您可以在这个&#34;每用户&#34;自举