Запустите команду "launchctl" под конкретным пользователем, используя NSTask в OS X

Мое приложение запускается под root, и мне нужно иметь возможность выгружать процессы с помощью NSTask и launchctl. Вот код, который я делаю:

    NSPipe *pipe = [NSPipe pipe];

    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath: @"/bin/launchctl"];
    [task setCurrentDirectoryPath:@"/"];
    [task setStandardError:pipe];

    NSLog(@"/bin/launchctl unload %@", plistAutostartLocation);

    NSArray *arguments;
    arguments = [NSArray arrayWithObjects: enableCommand, plistAutostartLocation, nil];
    [task setArguments: arguments];

    NSFileHandle * read = [pipe fileHandleForReading];

    [task launch];
    [task waitUntilExit];

Если процесс, который необходимо выгрузить, запускается с правами root, то он успешно выгружается, если не происходит сбой Вопрос в том, как запустить "launchctl" под конкретным пользователем (например, "myusername")?

Редактировать: в терминале, если я хочу запустить какую-то команду под конкретным пользователем, я делаю следующее, и это работает хорошо:

su - myusername -c "ls / Users / myusername"

Но когда я пытаюсь запустить "launchctl" под конкретным пользователем, это не удается:

su - myusername -c "launchctl load /Library/LaunchAgents/com.google.keystone.agent.plist"

Там написано: "ничего не найдено для загрузки"

1 ответ

Ошибка последней команды связана с пространствами имен начальной загрузки, вы пытаетесь загрузить агент в неправильном пространстве имен начальной загрузки. Система создает два разных пространства имен начальной загрузки, выдержка из документации Apple:

Стоит отметить различие между пространствами имен начальной загрузки и не-GUI для каждой сессии. Пространство имен начальной загрузки GUI создается инфраструктурой GUI (loginwindow а также WindowServer) когда пользователь входит в систему через графический интерфейс. Пространство имен начальной загрузки сеанса без графического интерфейса создается, когда пользователь входит в систему через SSH. Хотя между этими пространствами имен нет принципиальной разницы, службы на основе графического интерфейса, такие как Dock, регистрируются только в пространствах имен начальной загрузки для каждого интерфейса.

su команда не запускается в том же пространстве имен начальной загрузки, которое используется launchd,

Есть два способа выполнить команду, подобную той, которую вы хотите запустить в правильном пространстве имен начальной загрузки:

  • 10.10 и выше: используйте launchctl asuser, Это запустит любую команду, так как она была запущена указанным <myusername>, Стоит отметить, что вы должны запустить это как root, иначе команда не выполнится. Ваша последняя команда должна быть выполнена так:

     launchctl asuser <myusername> launchctl load "/Library/LaunchAgents/com.google.keystone.agent.plist"
    
  • 10.10 и ниже (с 10.11 SIP блокирует этот метод): используйте launchctl bsexec, Для этого требуется идентификатор процесса, чтобы получить правильное пространство имен для запуска другой команды. Кроме того, вы должны изменить UID команды вручную, например так:

    launctl bsexec <pid> su -u <myusername> launchctl load "/Library/LaunchAgents/com.google.keystone.agent.plist"
    
Другие вопросы по тегам