문제

루트 레벨 데몬에서 세션 당 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 세션에서 루트로 실행됩니다. 내가 sudo를 떠나면 거기에서 시작하면 나는 얻는다

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

BSEXEC의 다양한 순열 (부하/언로드 명령으로 BSEXEC에서 2 차 스크립트를 호출하는 포함)으로 엉망을 시도했지만 Root 이외의 다른 GUI 세션에서는 인스턴스를 시작할 수 없습니다. .

나는 또한 주위를 엉망으로 만들려고 노력했다 su - <user> ... 그리고 sudo -u <user> ..., 그러나 운이 없었습니다 (많은 사람들이 위의 연결된 기사와 다른 곳에서 논의했듯이).

아무도 생각이 있습니까?

편집 : Graham Lee가 아래에 제안한대로 래퍼 도구 로이 작업을 시도했지만 다음과 같은 오류가 발생합니다.

launch_msg(): Socket is not connected

이것은 명령 줄 명령, 래퍼 및 스크립트입니다 (501은 userId이고 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
도움이 되었습니까?

해결책

사용 launchctl bsexec 정확하지만 '실제'에이전트 실행 파일을 실행하기 전에 대상 사용자에게 UID를 떨어 뜨리는 래퍼 도구를 시작해야합니다. 아, 그리고 아마도 찾는 것이 더 낫다 loginwindow 프로세스, 로그인 세션의 리더이기 때문에 launchd 작동 할 가능성이 매우 높습니다).

다른 팁

USER 실행 인스턴스가 터미널에서 시작된 LaunchCTL과 동일한 부트 스트랩 네임 스페이스에서 실행되지 않은 것처럼 보입니다.

Dock.App을 PID 기증자로 사용하고 Sudo Magic :

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에서는 작동하지 않습니다. 예, 에이전트가 출시 될 것이지만, 올바른 상황이 아닌 테스트에서 볼 수 있듯이.

토론을 바탕으로 여기와 이 스크립트, 래퍼 도구가 필요하다고 생각하지 않았습니다. 이 두 개의 배쉬 스크립트는 다른 사람도 도움이 될 수 있습니다.

언로드 에이전트

#!/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 El Capitan (10.11)의 '루트가없는'으로 인해 BSEXEC의 사용은 더 이상 작동하지 않을 수 있지만 최대 10.10까지는 괜찮을 것입니다.

나는 같은 문제가 있었다. 이를 해결하려면 PID "아래"런치드를 사용하여 시작한 프로세스의 PID가 시작되었습니다.

당신이 'launchctl bsexec'에 커밋 한 PID는 올바른 부트 스트랩을 찾는 데 사용됩니다. Root Launchd Bootstrap에서 작업하는 것보다 시작 (사용자 컨텍스트)의 PID를 사용하는 경우. PE를 사용하는 경우. 사용자의 Finder 또는 Dock Pid,이 "사용자 당"부트 스트랩에서 작업 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top