Ответ 1
Во-первых, в вашем вопросе есть немного путаницы. Оба Shift + Control + Eject и Energy Saver помещают экраны в сон, что не то же самое, что блокировка. В зависимости от ваших других настроек это может также привести к блокировке экрана, но это отдельная проблема. IIRC, на Lion, по умолчанию, ни один из них никогда не заблокирует экран, но если вы оставите экран спальным дольше, чем время, установленное в разделе "Безопасность и конфиденциальность", это заблокирует его.
В любом случае API CGSessionCopyCurrentDictionary
позволяет вам получить информацию о спящем режиме экрана и блокировке экрана для сеанса графического интерфейса пользователя. Если у вас нет сеанса GUI (например, потому что вы работаете в оболочке ssh), или ваш сеанс не владеет консолью (например, потому что у кого-то есть выключение по быстрому пользователю) t получить эту информацию, но вы, по крайней мере, сможете обнаружить эти случаи.
Это единственный механизм, который я знаю о том, что работает для всех ОС с 10.5 (фактически 10.3) до 10.8 (но это не значит, что единственное, что на самом деле есть...).
Нет прямого способа вызвать это из bash или AppleScript. Однако вы можете использовать свой любимый мост (PyObjC, MacRuby, ASOC и т.д.), Чтобы называть его косвенно. Вот пример использования Python:
#!/usr/bin/python
import Quartz
d = Quartz.CGSessionCopyCurrentDictionary()
print d
Здесь как интерпретировать ответ:
- Если вы ничего не получите, то у вас нет сеанса пользовательского интерфейса.
- Если словарь имеет
kCGSSessionOnConsoleKey
= 0 или отсутствует, либо ваш сеанс GUI не владеет консолью, либо экраны консоли спадают. - Если словарь имеет
CGSSessionScreenIsLocked
= 1, экраны заблокированы.
Единственным проблемным случаем является то, что kCGSSessionOnConsoleKey
равно 0 (или отсутствует), а CGSSessionScreenIsLocked
равно 1. В этом случае вы включили экраны, чтобы спать и заблокировали их, или кто-то другой взял консоль и заблокировали экраны (с удержанием или без них). И я не уверен, есть ли способ различать эти случаи. Но если вы ищете "не пытайтесь отобразить диалог, потому что пользователю придется сначала разблокировать экран", оба этих случая означают "не отображать диалог".
Итак, это должно дать вам то, что вы хотите:
#!/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)
Или, превратив его в однострочный, вы можете поместить прямо в оболочку script:
python -c 'import sys,Quartz; d=Quartz.CGSessionCopyCurrentDictionary(); sys.exit(d and d.get("CGSSessionScreenIsLocked", 0) == 0 and d.get("kCGSSessionOnConsoleKey", 0) == 1)'
Теперь, что, если вы ssh'd на Mac, и вы также вошли в эту консоль Mac GUI (как тот же пользователь)? В этом случае ваш сеанс входа в ssh может связываться с сеансом входа в консоль точно так же, как и в локальной сессии входа в терминал. Таким образом, CGSessionCopyCurrentDictionary будет получать те же значения.
Сервер начальной загрузки, который опосредует это соединение, будет применять некоторые ограничения (например, security authorize -u foo
должен работать с терминалом, но не поверх ssh), но они не полностью документированы и изменяются с версии на версию, поэтому, возможно, на что вы хотите положиться. Вместо этого вы хотите действительно прочитать информацию о сеансе входа в систему
Если вы хотите продолжить работу с этим, начните с чтения Темы программирования нескольких пользователей. Но некоторая информация на самом деле нигде не документирована (например, как связаны сеансы уровня Mach, на которые ссылаются SessionGetInfo
и сеансы уровня BSD, на которые ссылаются utmpx
). Многие из соответствующих инструментов и библиотек с открытым исходным кодом могут помочь. Даже если вы читаете все это, не говорите вам, как делать то, что вы хотите, оно скажет вам, что именно вы хотите, и правильные условия для поиска и поиска вопросов, которые могут быть достаточно хорошими.