Запуск / остановка запуска агента для всех пользователей с сеансами графического интерфейса

Мне нужно иметь возможность запускать / останавливать агента 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

но это запускает / останавливает только один экземпляр и запускается от имени пользователя root в текущем сеансе графического интерфейса. Если я оставлю sudo там, я получу

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

Я пытался возиться с множеством других перестановок bsexec (включая вызов вторичного сценария из bsexec с помощью команды load / unload), но я никогда не смогу запустить экземпляр как что-то отличное от root и никогда в другом сеансе графического интерфейса ,

Я также пытался возиться сsu - <user> ... а такжеsudo -u <user> ..., но там тоже не повезло (как многие люди обсуждали в вышеупомянутых связанных статьях и в других местах).

У кого-нибудь есть мысли?

РЕДАКТИРОВАТЬ: Я попытался сделать это с помощью инструмента-обертки, как предложено ниже Грэмом Ли, но я получаю следующую ошибку:

launch_msg(): Socket is not connected

Это команда, оболочка и скрипт командной строки, которые я использую (501 - это идентификатор пользователя, а 63093 - идентификатор запуска для другого пользователя, вошедшего в систему):

Командная строка:

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

Ответы на вопрос(4)

Ваш ответ на вопрос