Запустите команду "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"