Próbuję wymyślić, jak uruchomić aplikację GUI jako inny użytkownik zalogowany interaktywnie, w sesji graficznej tego użytkownika.
Powiedzmy, że mam dwóch użytkowników, foo i bar. Oba są zalogowane, ale obecny użytkownik interaktywny to foo. Chciałbym uruchomić Calculator.app jako „pasek” użytkownika, aby po szybkim przełączeniu użytkownika na pasek znajdowałem okno kalkulatora w sesji paska.
Oto, co próbowałem, to nie działa:
sudo -u bar /Applications/Calculator.app/Contents/MacOS/Calculator
To uruchamia Calculator.app jako pasek, ale okno otwiera się w sesji graficznej foo.
sudo -u bar osascript -e "tell application \"Calculator\" to activate"
Ten sam efekt.
sudo -u bar open "/Applications/Calculator.app"
Uruchamia kalkulator jako foo, a nie pasek.
launchctl asuser [uid of bar] [any of the above commands]
Ten sam efekt.
Czy jest jakiś sposób na osiągnięcie tego? Jestem gotów zająć się wszelkimi możliwymi rozwiązaniami, w tym skryptami bash, AppleScript, pisaniem programu Core Foundation lub Cocoa i tak dalej. W mojej sytuacji każdy program lub skrypt może być uruchamiany jak każdy użytkownik, w tym root.
Uwaga: Zdaję sobie sprawę, że jest to możliwe przy użyciu zdalnych zdarzeń Apple, ale nie mogę tego użyć, ponieważ w tej sytuacji próbuję to zrobić, nie mam gwarancji, że „Zdalne zdarzenia Apple” zostaną włączone w preferencjach udostępniania.
Każda pomoc byłaby bardzo mile widziana!
źródło
open
poleceniaSSH
?Odpowiedzi:
To, co chcesz osiągnąć, jest możliwe, ale trudne. Musisz uruchomić aplikację w ramach odpowiedniej sesji użytkownika. Ze względów bezpieczeństwa przekroczenie podziału sesji użytkownika jest trudne.
Potrzebujesz procesu już uruchomionego w sesji innego użytkownika, aby wysłuchać twojego żądania i uruchomić aplikację w Twoim imieniu.
Wystartował bsexec
Na szczęście najnowsze wersje
launchd
mają tę zdolność; chociaż inżynierowie Apple nie zalecili jego ogólnego zastosowania. Użyjbsexec
opcji w launchctl, aby wybrać odpowiednią sesję użytkownika:Zalecanym podejściem jest napisanie uruchomionego biletu zadania i zrestartowanie komputera Mac - lub poproszenie użytkownika o wylogowanie i ponowne zalogowanie.
Przyczyna problemów
Problemy wynikają z połączenia aplikacji z niewłaściwym
WindowServer
procesem. Każda sesja użytkownika ma osobny WindowServer; ten proces obsługuje interfejs użytkownika. Wcześniejsze metody przypisują własność procesu właściwemu użytkownikowi, ale są połączone z własnym procesem WindowServer.Ten problem jest wymieniony w nocie technicznej Daemons and Agents od Apple.
Doświadczenie
Wiem to z własnego doświadczenia. Dla Power Managera napisałem pmuser, aby istniał w każdej sesji użytkownika.
pmuser
nasłuchuje naszego demona i obsługuje uruchomienia i polecenia dla poszczególnych użytkowników. Pomimo tego, że nasz demon ma uprawnienia administratora, nadal potrzebowaliśmy procesu na użytkownika, aby działać niezawodnie w sesjach użytkowników.źródło
Żadna z powyższych odpowiedzi bsesek nie działa na El Capitan (10.11), ze względu na zamknięcie portów przez System Integration Protection (SIP). „launchctl asuser” działa, ale wymaga uruchomienia jako root. Poniższe polecenie działa w El Capitan (i najnowszych systemach operacyjnych):
Zauważ, że 501 jest identyfikatorem użytkownika dla mojego innego użytkownika.
źródło
bruno.medeiros@brunojcm-macbook:~ $ sudo launchctl asuser 501 open /Applications/Firefox.app
i dostałemLSOpenURLsWithRole() failed with error -600 for the file /Applications/Firefox.app
sudo launchctl asuser $(id -u <user_id_name>) <app>
. To powiedziawszy, otrzymuję inny błąd,posix_spawn(): 13: Permission denied
nawet jeśli uruchamiam z tym samym identyfikatorem użytkownika, z którym jestem zalogowany (i jestem właścicielem sesji) dlasudo launchctl asuser $(id -u mtylutki) /Applications/Calculator.app
Ponieważ ostatecznie 10.10 zapewnia poprawną implementację „launchctl bsexec”, możesz użyć:
człowiek mówi
Tak więc jako parametr PID możesz użyć pid odpowiedniego procesu logowania do okna . UID to identyfikator użytkownika posiadającego loginwindow, a GID to jego podstawowa grupa.
Działa to dobrze dla każdego polecenia i oczywiście dla uruchomionych zadań (np. Launchagents), w końcu także:
źródło
task_for_pid(): 0x5
błąd, w którym sprawdziłem, czy PID jest poprawny.Możesz użyć Findera jako hosta dla odpowiednich uprawnień
osascript -e "tell application \"Finder\" to open (\"${app}\" as POSIX file as alias)"
. W ten sposób uruchomi się za pomocą dowolnego kontekstu GUI uruchomionego Findera.źródło
Działa to przez ssh:
ale jeśli spróbujesz za pośrednictwem Terminal.app, to otworzy TextEdit w GUI bieżącego użytkownika.
Jeśli nie masz pewności, czy
ssh
jest włączona, być może możesz ją tymczasowo włączyći wyłącz go później, jeśli to konieczne?
W przeciwnym razie jestem zakłopotany.
Testowane na 10.9.
źródło
Prosty
następnie wykonuj polecenia normalnie.
źródło
bar
, ale nadal działałyby wfoo
sesji graficznej.