No pude encontrar una forma de ejecutar un script para la cuenta de invitado durante el inicio de sesión que se ejecuta cada minuto. Dicen que usar cron daemon está en desuso, por lo que parece que usaré launchd con archivos .plist.
Escenario: tengo un iMac público. Quiero permitir que el público en general use la cuenta de invitado y forzar el cierre de sesión cada media hora. Escribí un script Ruby para verificar el tiempo de inicio de sesión y calcular el tiempo restante. Puedo hacer que muestre una notificación de banner cada 10 minutos usando osascript y luego cerrar sesión en mi cuenta. El problema es que cuando trato de implementarlo para la cuenta de invitado, no funciona.
El problema es cuando coloco el archivo .plist dentro de /Library/LaunchDaemons, ya que se ejecuta después de iniciar sesión y también se ejecuta como root. Ejecutar como root es importante ya que puedo tener el privilegio de cerrar procesos cuando se acaba el tiempo. Necesito que se ejecute una vez cada minuto. Este es el archivo plist actual que funciona cuando inicio sesión como mi propio nombre de usuario "propietario" pero no como invitado. Usando org.user.plist
Mi archivo .plist original se veía así
<?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>
Actualización 1 (Todavía no es una solución) Archivo .plist que se ejecuta cada 10 segundos tanto para Invitado como para mi nombre de usuario
<?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>
Como prueba para asegurarme de que aparece el banner de notificación de osascript, tengo este código dentro de /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"'
La solución está abajo.
En mi opinión, lo siguiente debería funcionar: ¡lo hace en mi máquina virtual! - lanzado como /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>
Como tarea de ejemplo utilizo /usr/bin/touch -f /Users/Guest/Desktop/test.txt
.
El truco aquí es que el contenido completo de la carpeta Invitado se elimina después de cerrar la sesión. Después de que un nuevo invitado inicia sesión, todo el contenido se vuelve a crear desde cero. Tan pronto como se crea la carpeta /Users/Guest/Library, touch ...
se inicia la tarea de ejemplo ( ) debido a la clave WatchPaths.
Dado que la tarea/secuencia de comandos/aplicación debe ejecutarse como invitado, no puede usar agentes de lanzamiento porque la ruta /Users/Guest/Library/LaunchAgents/ simplemente no existe.
Utilice un demonio de lanzamiento en su lugar y ejecútelo como Guest/_guest . ¿Su secuencia de comandos ruby /usr/local/bin/notify-custom tiene que ser legible/ejecutable en todo el mundo? por supuesto.
También traté de ejecutar la tarea cada 60 segundos, lo que funciona correctamente pero arroja algunos errores después de que el invitado cierra la sesión. Probablemente sea mejor implementar todo en el script Ruby. Sin embargo, dependiendo de su guión, su kilometraje puede variar.
Si tiene dos tareas diferentes para ejecutar (por ejemplo, mostrar un banner cada 10 minutos con Ruby y un temporizador para forzar el cierre de sesión después de 30 minutos), probablemente sea mejor crear dos demonios de lanzamiento diferentes.
/Library/LaunchAgents
y sin el uso de WatchPaths
la clave , así como lo hicieron otros LaunchAgents desde la misma ubicación./Library/LaunchAgents
, el que creé para esta prueba y 2 existentes que fueron agregados por aplicaciones que se ejecutan en el sistema, por ejemplo, Little Snitch. Entonces, en general, no veo un problema al usar LaunchAgents para tomar medidas en la cuenta de invitado. Dicho esto, ciertamente puede depender exactamente de lo que uno está tratando de hacer que puede hacer que el uso de LaunchAgents en /Library/LaunchAgents
este escenario de caso de uso no sea ideal. Solo puedo seguir mis pruebas y funcionó para mí de la manera en que probé. No sé qué más puedo decir.Resuelto. He estado trabajando en esto por un tiempo. Mi solución finalmente hace lo que necesito y es que se inicia durante el inicio de sesión para el usuario Invitado (y como opción, también lo tengo iniciando para mí, el usuario iMac1, solo para mostrar el tiempo de inicio de sesión). No vi una forma sencilla de poner el archivo org.user.plist en /Users/Guest/Library/LaunchAgents que teóricamente lo habría lanzado cuando el Invitado inició sesión y la razón por la que abandoné esa situación es porque esa carpeta no se crea hasta el inicio de sesión.
Lo que hice fue poner mi archivo .plist dentro de /Library/LaunchAgents/ que se ejecuta para cada usuario. Eso está bien ya que mi código distinguirá al usuario invitado y tomará medidas (en este caso, cerrará la sesión después del tiempo establecido).
El archivo .plist final:
<?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>
Tenga en cuenta que agregué una clave RunAtLoad ya que sin ella, el script se ejecutó pero esperó un minuto para activar su primer evento. Si, en cambio, utilicé la clave WatchPaths como señaló @klanomath en su comentario, entonces el script se ejecutaría cada 10 segundos, ya que debe haber actividad en esa carpeta con regularidad. Solo quería que se ejecutara cada 60 segundos por ahora. Podría cambiar ese temporizador más adelante cuando limpie todo el procedimiento con algunos diálogos de advertencia más coloridos escritos en Python.
Aquí está el código Ruby dentro de /usr/local/bin/notify-custom que se ejecuta para cada inicio de sesión de usuario:
#!/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
Nuevamente, tenga en cuenta que si usa LaunchDaemons en su lugar, se ejecutan bajo la cuenta raíz del sistema mientras que los Agentes se ejecutan en la cuenta de los usuarios que iniciaron sesión. Usando la segunda opción, tuve que dar permiso al usuario Invitado para ejecutar Sudo shutdown como @klanomath mencionado a continuación. Esto se hizo ejecutando el comando: $sudo visudo y agregando lo siguiente al final del archivo:
Guest ALL=NOPASSWD: /sbin/shutdown
También quería mostrar solo la cuenta de invitado en la página de inicio de sesión, así que oculté mi cuenta de esa pantalla con este comando:
sudo dscl . create /Users/hiddenuser IsHidden 1
y si cambia de opinión, puede traerlo de vuelta con:
sudo dscl . create /Users/hiddenuser IsHidden 0
Gracias @klanomath y @user3439894
usuario3439894
mickey d
usuario3439894
notify-custom
y es un binario o un script, y si es el último, cuál es el contenido del script?mickey d
usuario3439894
root
delwheel
grupo con0644
permisos/Library/LaunchAgents
y se ejecutó cuando inicié sesión como Invitado. Con la excepción de la cadena para la clave del programa , el resto del archivo era el mismo. Funcionó como se esperaba. También miro a los otros LaunchAgents en la misma ubicación y verifico en el Monitor de actividad que sus procesos también comenzaron. Entonces, sin saber quénotify-custom
es y su contenido, no hay mucho más que pueda ofrecer en este momento, aparte de los archivos .plist en el/Library/LaunchAgents
trabajo en la cuenta de invitado.usuario3439894
mickey d
klanomath
klanomath
sudo shutdown
para un usuario invitado que modifique el archivo /etc/sudoers debería funcionar.mickey d
mickey d
klanomath