Ich konnte keine Möglichkeit finden, während der Anmeldung ein Skript für das Gastkonto auszuführen, das jede Minute ausgeführt wird. Sie sagen, dass die Verwendung des Cron-Daemons veraltet ist, also sieht es so aus, als würde ich launchd mit .plist-Dateien verwenden.
Szenario: Ich habe einen öffentlichen iMac. Ich möchte der Allgemeinheit erlauben, das Gastkonto zu verwenden, und alle halbe Stunde eine Abmeldung erzwingen. Ich habe ein Ruby-Skript geschrieben, um die Anmeldezeit zu überprüfen und die verbleibende Zeit herauszufinden. Ich kann mit osascript alle 10 Minuten eine Bannerbenachrichtigung anzeigen und mich dann von meinem Konto abmelden lassen. Das Problem ist, wenn ich versuche, es für das Gastkonto zu implementieren, funktioniert es nicht.
Das Problem ist, wenn ich die .plist-Datei in /Library/LaunchDaemons platziere, da sie nach der Anmeldung und auch als Root ausgeführt wird. Das Ausführen als root ist wichtig, da ich das Privileg haben kann, Prozesse herunterzufahren, wenn die Zeit abläuft. Ich brauche es, um einmal pro Minute auszuführen. Dies ist die aktuelle Plist-Datei, die funktioniert, wenn ich mich als mein eigener Benutzername "Besitzer", aber nicht als Gast anmelde. Verwenden von org.user.plist
Meine ursprüngliche .plist-Datei sah ungefähr so aus
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.user</string>
<key>Program</key>
<string>/usr/local/bin/notify-custom</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Update 1 (Noch keine Lösung) .plist-Datei, die alle 10 Sekunden für Gast und meinen Benutzernamen ausgeführt wird
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.user</string>
<key>ProgramArguments</key>
<string>/usr/local/bin/notify-custom</string>
<key>WatchPaths</key>
<array>
<string>/Users/Guest/Library</string>
<string>/Users/owner/Library</string>
<array>
</integer>
</dict>
</plist>
Als Test, um sicherzustellen, dass das osascript-Benachrichtigungsbanner erscheint, habe ich diesen Code in /usr/local/bin/notify-custom
#/bin/bash
#Using whoami would have shown me logged in as root under LaunchDaemon .plist
loggedinUser=`finger | awk 'NR==3{print $1}'`
#I need to manually run terminal and type sudo as guest for nextline to work
sudo -u $loggedinUser /usr/bin/osascript -e 'display notification "Test" with title "Banner Notification"'
Lösung ist unten.
Meiner Meinung nach sollte Folgendes funktionieren - es funktioniert in meiner VM! - gestartet als /Library/LaunchDaemons/org.user.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.user</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/touch</string>
<string>-f</string>
<string>/Users/Guest/Desktop/test.txt</string>
</array>
<key>UserName</key>
<string>Guest</string>
<key>GroupName</key>
<string>_guest</string>
<key>InitGroups</key>
<true/>
<key>WatchPaths</key>
<array>
<string>/Users/Guest/Library</string>
</array>
</dict>
</plist>
Als Beispielaufgabe verwende ich /usr/bin/touch -f /Users/Guest/Desktop/test.txt
.
Der Clou dabei ist, dass nach einem Logout der komplette Inhalt des Guest-Ordners gelöscht wird. Nachdem sich ein neuer Gast anmeldet, wird der gesamte Inhalt von Grund auf neu erstellt. Sobald der Ordner /Users/Guest/Library angelegt ist, touch ...
wird der Beispieltask ( ) aufgrund des WatchPaths-Schlüssels gestartet.
Da die Aufgabe/das Skript/die App als Gast ausgeführt werden muss, können Sie keine Startagenten verwenden, da der Pfad /Users/Guest/Library/LaunchAgents/ einfach nicht existiert.
Verwenden Sie stattdessen einen Launch-Daemon und führen Sie ihn als Guest/_guest aus . Ihr Ruby-Skript /usr/local/bin/notify-custom muss weltweit lesbar/ausführbar sein? Natürlich.
Ich habe auch versucht, die Aufgabe alle 60 Sekunden auszuführen - was ordnungsgemäß funktioniert, aber nach dem Abmelden des Gastes einige Fehler auslöst. Wahrscheinlich ist es besser, das Ganze im Ruby-Skript zu implementieren. Abhängig von Ihrem Skript kann Ihr Kilometerstand jedoch variieren.
Wenn Sie zwei verschiedene Aufgaben ausführen müssen (z. B. mit Ruby alle 10 Minuten ein Banner anzeigen und einen Timer zum Erzwingen der Abmeldung nach 30 Minuten), ist es wahrscheinlich besser, zwei verschiedene Start-Daemons zu erstellen.
/Library/LaunchAgents
und ohne die Verwendung des WatchPaths
Schlüssels ausgeführt wurde, ebenso wie andere LaunchAgents vom selben Standort aus./Library/LaunchAgents
, den, den ich für diesen Test erstellt habe, und 2 vorhandene, die von Anwendungen hinzugefügt wurden, die auf dem System ausgeführt werden, z. B. Little Snitch. Daher sehe ich im Allgemeinen kein Problem bei der Verwendung eines LaunchAgents, um Aktionen im Gastkonto durchzuführen. Allerdings kann es sicherlich davon abhängen, was genau man zu tun versucht, was die Verwendung eines LaunchAgents in /Library/LaunchAgents
diesem Anwendungsfall-Szenario möglicherweise nicht ideal macht. Ich kann mich nur an meine Tests halten und es hat bei mir so funktioniert, wie ich es getestet habe. Ich weiß nicht, was ich noch sagen kann.Gelöst. Daran arbeite ich schon eine Weile. Meine Lösung tut endlich das, was ich brauche, und das heißt, sie startet während der Anmeldung für den Benutzer Gast (und als Option habe ich sie auch für mich selbst, den Benutzer iMac1, gestartet, nur um die Anmeldezeit anzuzeigen). Ich habe keine einfache Möglichkeit gesehen, die Datei org.user.plist in /Users/Guest/Library/LaunchAgents abzulegen, die sie theoretisch gestartet hätte, wenn sich der Gast angemeldet hätte, und der Grund, warum ich diese Situation aufgegeben habe, ist dieser Ordner wird erst nach der Anmeldung erstellt.
Ich habe meine .plist-Datei in /Library/LaunchAgents/ abgelegt, die für jeden Benutzer ausgeführt wird. Das ist in Ordnung, da mein Code den Guest-Benutzer unterscheidet und Maßnahmen ergreift (in diesem Fall nach der festgelegten Zeit abmelden).
Die endgültige .plist-Datei:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.user</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/notify-custom</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>60</integer>
</dict>
</plist>
Beachten Sie, dass ich einen RunAtLoad-Schlüssel hinzugefügt habe, da das Skript ohne ihn ausgeführt wurde, aber eine Minute gewartet hat, um sein erstes Ereignis auszulösen. Wenn ich stattdessen den WatchPaths-Schlüssel verwenden würde, wie @klanomath in seinem Kommentar bemerkte, würde das Skript alle 10 Sekunden ausgeführt, da ihre Aktivitäten regelmäßig in diesem Ordner stattfinden müssen. Ich wollte nur, dass es vorerst alle 60 Sekunden läuft. Ich kann diesen Timer später ändern, wenn ich die gesamte Prozedur mit einigen farbenfroheren Warndialogen aufräume, die in Python geschrieben sind.
Hier ist der Ruby-Code in /usr/local/bin/notify-custom, der bei jeder Benutzeranmeldung ausgeführt wird:
#!/usr/bin/ruby -w
require 'time'
require 'FileUtils'
loggedinUser=`finger|awk 'END{print $1}'`.strip
getloginTime=`finger|awk 'END{print}'|cut -c49-53`
getnowTime=`date|awk 'NR==1{print $4}'`[0..4]
loginTime=(Time.parse(getloginTime).to_i)
nowTime=(Time.parse(getnowTime).to_i)
diffSec=(nowTime-loginTime)
diffMin=(diffSec/60)
timeRemain=30-diffMin
#To see some console output while debugging
puts "getloginTime =#{getloginTime}"
puts "getnowTime =#{getnowTime}"
puts "loginTime=#{loginTime}"
puts "nowTime =#{nowTime}"
puts "timeRemain=#{timeRemain}"
if loggedinUser == "Guest"
open("/Users/#{loggedinUser}/Desktop/30 Minutes Max Use Per Day",'a'){|f| f.puts "With this new iMac, you are limited to a maximum of 1/2 hour use per day"}
if timeRemain < 0
`/usr/bin/osascript -e 'tell application "Finder" to set desktop picture to POSIX file "/Library/Desktop Pictures/Earth Horizon.jpg"'`
`/usr/bin/osascript -e 'display notification "SHUTTING DOWN! Now= #{getnowTime} LoggedInAt=#{getloginTime} TimeRemain=#{timeRemain}" with title "Guest SHUTTING DOWN" sound name "Glass"'`
`/usr/bin/osascript -e 'tell app "Terminal" to do script "sudo shutdown -h now"'`
else
`/usr/bin/osascript -e 'display notification "Now= #{getnowTime} TimeRemain=#{timeRemain}" with title "#{loggedinUser} TIME LOGGED IN= #{getloginTime}" subtitle "User= #{loggedinUser}"'`
end
else
`/usr/bin/osascript -e 'display notification "Now= #{getnowTime} TimeRemain=#{timeRemain}" with title "#{loggedinUser} TIME LOGGED IN= #{getloginTime}" subtitle "User= #{loggedinUser}"'`
end
Beachten Sie erneut, dass, wenn Sie stattdessen die LaunchDaemons verwenden, diese unter dem System-Root-Konto ausgeführt werden, während die Agenten auf dem angemeldeten Benutzerkonto ausgeführt werden. Mit der zweiten Option musste ich dem Gastbenutzer die Berechtigung erteilen, sudo shutdown wie unten erwähnt @klanomath auszuführen. Dazu wurde der Befehl $sudo visudo ausgeführt und am Ende der Datei Folgendes hinzugefügt:
Guest ALL=NOPASSWD: /sbin/shutdown
Außerdem wollte ich nur das Gastkonto auf der Anmeldeseite anzeigen, also habe ich mein Konto mit diesem Befehl auf diesem Bildschirm ausgeblendet:
sudo dscl . create /Users/hiddenuser IsHidden 1
und wenn Sie Ihre Meinung ändern, können Sie es zurückbringen mit:
sudo dscl . create /Users/hiddenuser IsHidden 0
Danke @klanomath und @user3439894
Benutzer3439894
Micky D
Benutzer3439894
notify-custom
und ist es eine Binärdatei oder ein Skript, und wenn letzteres, was ist der Inhalt des Skripts?Micky D
Benutzer3439894
root
in derwheel
Gruppe mit0644
Berechtigungen ist,/Library/LaunchAgents
und sie lief, wenn sie als Gast angemeldet war. Mit Ausnahme der Zeichenfolge für die Programmtaste war der Rest der Datei gleich. Es funktionierte wie erwartet. Ich schaue mir auch die anderen LaunchAgents am selben Ort an und überprüfe im Aktivitätsmonitor, dass ihre Prozesse ebenfalls gestartet wurden. Ohne zu wissen, was esnotify-custom
ist und was es enthält, kann ich im Moment nicht viel anderes anbieten, als zu sagen, dass .plist-Dateien/Library/LaunchAgents
im Gastkonto in Arbeit sind.Benutzer3439894
Micky D
klanomath
klanomath
sudo shutdown
für einen Gastbenutzer zu aktivieren, der die Datei /etc/sudoers ändert, sollte funktionieren!Micky D
Micky D
klanomath