Я пытаюсь понять, как запустить приложение с графическим интерфейсом от имени другого пользователя, который вошел в систему интерактивно, в графическом сеансе этого пользователя.
Например, у меня есть два пользователя, foo и bar. Оба вошли в систему, но текущий интерактивный пользователь — foo. Я хотел бы запустить Calculator.app как пользовательскую «панель», чтобы при быстром переключении пользователя на панель я обнаружил, что окно калькулятора открыто в сеансе панели.
Вот что я пробовал, что не работает:
sudo -u bar /Applications/Calculator.app/Contents/MacOS/Calculator
Это запускает Calculator.app как панель, но окно открывается в графическом сеансе foo.
sudo -u bar osascript -e "tell application \"Calculator\" to activate"
Тот же эффект.
sudo -u bar open "/Applications/Calculator.app"
Запускает калькулятор как foo, а не как bar.
launchctl asuser [uid of bar] [any of the above commands]
Тот же эффект.
Есть ли способ сделать это? Я готов рассматривать всевозможные возможные решения, включая сценарии bash, AppleScript, написание программы Core Foundation или Cocoa и так далее. В моей ситуации любая программа или скрипт могли выполняться от имени любого пользователя, включая root.
Примечание. Я знаю, что можно использовать удаленные события Apple, но я не могу использовать это, поскольку в ситуации, в которой я пытаюсь это сделать, у меня нет гарантии, что «Удаленные события Apple» будут включены в настройках общего доступа.
Любая помощь будет принята с благодарностью!
Ни один из приведенных выше ответов bsexec не работает на El Capitan (10.11) из-за закрытия портов защитой системной интеграции (SIP). «launchctl asuser» работает, но требует запуска от имени пользователя root. Приведенная ниже команда работает на El Capitan (и самых последних ОС):
sudo launchctl asuser 501 open /Applications/Calculator.app
Обратите внимание, что 501 — это идентификатор другого моего пользователя.
bruno.medeiros@brunojcm-macbook:~ $ sudo launchctl asuser 501 open /Applications/Firefox.app
, и получилLSOpenURLsWithRole() failed with error -600 for the file /Applications/Firefox.app
sudo launchctl asuser $(id -u <user_id_name>) <app>
. Тем не менее, я получаю другую ошибку, posix_spawn(): 13: Permission denied
даже если я работаю с тем же идентификатором пользователя, с которым я вошел в систему (и владеет сеансом) дляsudo launchctl asuser $(id -u mtylutki) /Applications/Calculator.app
То, чего вы хотите достичь, возможно, но сложно. Вам необходимо запустить приложение в рамках соответствующего пользовательского сеанса. Из соображений безопасности пересечение границы сеанса пользователя затруднено.
Вам нужен процесс, уже запущенный в сеансе другого пользователя, чтобы прослушать ваш запрос и запустить приложение от вашего имени.
К счастью, в последних версиях launchd
есть такая возможность; хотя инженеры Apple не рекомендовали его повсеместное использование. Используйте bsexec
параметр в launchctl , чтобы выбрать соответствующий сеанс пользователя:
bslist [PID | ..] [-j]
This prints out Mach bootstrap services and their respective states. While the namespace
appears flat, it is in fact hierarchical, thus allowing for certain services to be only avail-
able to a subset of processes. The three states a service can be in are active ("A"), inactive
("I") and on-demand ("D").
If [PID] is specified, print the Mach bootstrap services available to that PID. If [..] is
specified, print the Mach bootstrap services available in the parent of the current bootstrap.
Note that in Mac OS X v10.6, the per-user Mach bootstrap namespace is flat, so you will only
see a different set of services in a per-user bootstrap if you are in an explicitly-created
bootstrap subset.
If [-j] is specified, each service name will be followed by the name of the job which regis-
tered it.
bsexec PID command [args]
This executes the given command in the same Mach bootstrap namespace hierachy as the given
PID.
bstree [-j]
This prints a hierarchical view of the entire Mach bootstrap tree. If [-j] is specified, each
service name will be followed by the name of the job which registered it. Requires root priv-
ileges.
Рекомендуемый подход состоит в том, чтобы написать билет задания launchd и перезапустить Mac или попросить пользователя выйти из системы и снова войти в нее.
Проблемы возникают из-за того, что приложение подключено к неправильному WindowServer
процессу. Каждый пользовательский сеанс имеет отдельный WindowServer; этот процесс обрабатывает пользовательский интерфейс. Ваши более ранние методы передают право собственности на процесс правильному пользователю, но подключенному к вашему собственному процессу WindowServer.
Эта проблема упоминается в технической заметке о демонах и агентах от Apple.
Я знаю это из личного опыта. Для Power Manager я написал, что pmuser существует в каждом пользовательском сеансе. pmuser
слушает нашего демона и обрабатывает запуск и команды для каждого пользователя. Несмотря на то, что у нашего демона есть полномочия root, нам по-прежнему нужен процесс для каждого пользователя, чтобы надежно работать в пользовательских сеансах.
Поскольку, наконец, 10.10 предоставляет правильную реализацию «launchctl bsexec», которую вы можете использовать:
sudo /bin/launchctl bsexec PID chroot -u UID -g GID / open /Applications/TextWrangler.app
человек говорит
Это выполняет данную команду в контексте выполнения, максимально похожем на целевой PID.
Таким образом, в качестве параметра PID вы можете использовать pid соответствующего процесса входа в систему . UID — это идентификатор пользователя, которому принадлежит это окно входа в систему, а GID — это его основная группа.
Это отлично работает для любой команды и, конечно же, для заданий запуска (например, агентов запуска), например:
/bin/launchctl bsexec 104 chroot -u 501 -g 20 / /bin/launchctl load -S Aqua /Library/LaunchAgents/com.youragent.plist 2>&1
task_for_pid(): 0x5
теперь я получаю сообщение об ошибке, когда я проверил правильность PID.Вы можете использовать Finder в качестве хоста для получения необходимых разрешений osascript -e "tell application \"Finder\" to open (\"${app}\" as POSIX file as alias)"
. Таким образом, он будет запускаться через любой контекст GUI, запущенный Finder.
Это работает через ssh:
#!/bin/bash
PID=$(ps auxwww | egrep "^bar" |\
fgrep /System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow |\
awk '{print $2}')
sudo launchctl bsexec "$PID" open -a TextEdit
но если попробовать через Terminal.app, то он открывает TextEdit в графическом интерфейсе текущего пользователя.
Если вы не уверены, что ssh
он включен, возможно, вы можете временно включить его.
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
и отключить его снова, если это необходимо?
Иначе я в тупике.
Проверено 10.9.
Простой
sudo su name_of_user
затем выполнять команды в обычном режиме.
bar
, но все равно будут выполняться в foo
графическом сеансе .
Матье Риглер
open
команду, используяSSH
?Бри Бри
Эшли
Хофи