2012-07-16 19 views
14

C'è un modo per controllare se lo schermo è bloccato nella shell o nel applescript? Non solo controllare se lo screensaver è in esecuzione, ma lo schermo è bloccato da impostazioni di risparmio energetico o premendo ^⇧⏏ (del cambio del + + espulsione).OSX: controlla se lo schermo è bloccato

Grazie in anticipo.

risposta

20

In primo luogo, c'è un po 'di confusione nella domanda. Sia Shift + Control + Eject che Energy Saver mettono a riposo gli schermi, il che non è la stessa cosa che bloccarli. A seconda delle altre impostazioni, questo potrebbe anche comportare il blocco dello schermo, ma questo è un problema separato. IIRC, su Lion, per impostazione predefinita, nessuno dei due bloccherà mai lo schermo, ma se si lascia lo schermo inattivo per più tempo rispetto al tempo impostato in Sicurezza & Privacy, questo verrà bloccato.

In ogni caso, l'API CGSessionCopyCurrentDictionary consente di ottenere informazioni su entrambe le schermate di sospensione e blocco schermo, per la sessione della GUI. Se non si dispone di una sessione della GUI (ad esempio, perché si sta eseguendo in una shell ssh), o se la sessione non è proprietaria della console (ad esempio, poiché qualcuno ha disattivato l'utente veloce), si è vinto ' essere in grado di ottenere queste informazioni, ma almeno sarete in grado di rilevare questi casi.

Questo è l'unico meccanismo che conosco che funzioni per tutti i sistemi operativi da 10.5 (in realtà da 10.3) a 10.8 (ma ciò non significa che sia l'unico in cui ci sia effettivamente ...).

Non esiste un modo diretto per chiamare questo da bash o AppleScript. Tuttavia, puoi usare il tuo bridge preferito (PyObjC, MacRuby, ASOC, ecc.) Per chiamarlo indirettamente. Ecco un esempio di utilizzo di Python:

#!/usr/bin/python 
import Quartz 
d = Quartz.CGSessionCopyCurrentDictionary() 
print d 

Ecco come interpretare la risposta:

  • Se si ottiene nulla in cambio, allora non si dispone di una sessione utente.
  • Se il dizionario ha kCGSSessionOnConsoleKey = 0 o non è presente, la sessione della GUI non è proprietaria della console o gli schermi della console sono addormentati.
  • Se il dizionario ha CGSSessionScreenIsLocked = 1, le schermate sono bloccate.

Il caso unico problema è dove kCGSSessionOnConsoleKey è 0 (o mancante) e CGSSessionScreenIsLocked è 1. In questo caso, sia che hai messo le schermate per dormire e li bloccato, o qualcun altro ha preso la console e bloccato gli schermi (con o senza metterli a dormire). E non sono sicuro se c'è un modo per distinguere tra questi casi. Ma se stai cercando "non provare a visualizzare una finestra di dialogo perché l'utente dovrà prima sbloccare lo schermo", entrambi i casi significano "non visualizzare una finestra di dialogo".

Quindi, questo dovrebbe darvi ciò che si vuole:

#!/usr/bin/python 
import sys 
import Quartz 
d=Quartz.CGSessionCopyCurrentDictionary() 
sys.exit(d and 
     d.get("CGSSessionScreenIsLocked", 0) == 0 and 
     d.get("kCGSSessionOnConsoleKey", 0) == 1) 

Oppure, trasformandolo in una battuta si può mettere direttamente in uno script di shell:

python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); sys.exit(d and d.get("CGSSessionScreenIsLocked", 0) == 0 and d.get("kCGSSessionOnConsoleKey", 0) == 1)' 

Ora, che cosa se hai ssh'd su un Mac e sei anche attualmente connesso alla console GUI di quel Mac (come lo stesso utente)?In tal caso, la sessione di accesso ssh può comunicare con la sessione di accesso della console esattamente nello stesso modo in cui avverrebbe una sessione di accesso Terminal locale. Quindi, CGSessionCopyCurrentDictionary otterrà gli stessi valori.

Il server di bootstrap che media quella connessione applicherà alcune restrizioni (ad esempio, security authorize -u foo dovrebbe funzionare dal terminale ma non su ssh), ma questi non sono completamente documentati e cambiano da versione a versione, quindi probabilmente non è qualcosa tu vuoi fare affidamento su Invece, si desidera leggere effettivamente le informazioni della sessione di login

Se si desidera andare oltre, iniziare con la lettura Multiple User Environments Programming Topics. Ma alcune informazioni non sono realmente documentate da nessuna parte (ad esempio, come le sessioni a livello di Mach a cui fa riferimento lo SessionGetInfo e le sessioni a livello BSD a cui fa riferimento utmpx sono collegate insieme). Molti degli strumenti e delle librerie rilevanti sono open source, che può essere di aiuto. Anche se la lettura di tutto ciò non ti dice come fare ciò che vuoi, ti dirà esattamente quello che vuoi e i termini giusti da usare per cercare e porre domande, che può essere abbastanza buono.

+0

Intendo "blocco" perché uno di questi stati blocca il mio computer a causa delle impostazioni di sicurezza (richiede immediatamente la password per sleep e screen saver). E grazie per la risposta dettagliata. In realtà ho risolto il mio compito analizzando _ioreg -n IODisplayWrangler_ per lo stato di alimentazione corrente. – LevB

+0

Grazie per questo; Stavo cercando di capire se l'utente era su una sessione della GUI o no, e il modulo Quartz python sembra molto utile. (purtroppo, quando sono SSH in un Mac, lo snippet di script restituisce lo stesso output di quando sono nella console della GUI.) So di poter controllare le variabili di ambiente specifiche di SSH, ma volevo diventa più preciso ... – mpontillo

+0

Dato che il mio commento è troppo lungo per essere adattato, lo aggiungerò alla risposta sopra. – abarnert

Problemi correlati