OSX:检查屏幕是否被锁定

时间:2012-07-16 13:21:29

标签: macos shell applescript

有没有办法检查屏幕是否被锁定在shell或applescript中? 不只是检查屏幕保护程序是否正在运行,但屏幕是通过节能设置锁定还是按 ^⇧⏏ shift + control + 弹出)。

提前谢谢。

2 个答案:

答案 0 :(得分:24)

首先,你的问题有点混乱。 Shift + Control + Eject和Energy Saver都将屏幕置于睡眠状态,这与锁定屏幕不同。根据您的其他设置,这可能还需要锁定屏幕,但这是一个单独的问题。 IIRC,在Lion上,默认情况下,任何人都不会锁定屏幕 - 但是如果你让屏幕睡得比安全和放大的时间更长。隐私,这将锁定它。

无论如何,API CGSessionCopyCurrentDictionary允许您获取有关GUI会话的屏幕睡眠和屏幕锁定的信息。如果您没有GUI会话(例如,因为您在ssh shell中运行),或者您的会话不拥有控制台(例如,因为有人快速用户将您切换出来),您就赢了能够获得此信息,但您至少能够检测到这些情况。

这是我所知道的唯一适用于从10.5(实际上是10.3)到10.8的所有操作系统的机制(但这并不意味着它实际上是唯一的......)。

没有直接的方法可以从bash或AppleScript中调用它。但是,您可以使用自己喜欢的桥(PyObjC,MacRuby,ASOC等)间接调用它。以下是使用Python的示例:

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

以下是解释响应的方法:

  • 如果您什么也没收到,那么您就没有UI会话。
  • 如果字典有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)

或者,将其转换为单行,您可以直接放入shell脚本:

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

现在,如果您已经进入Mac,并且当前已登录到该Mac的GUI控制台(作为同一用户),该怎么办?在这种情况下,您的ssh登录会话可以与控制台登录会话进行通信,其方式与本地终端登录会话完全相同。因此,CGSessionCopyCurrentDictionary将获得相同的值。

调解该连接的引导服务器将应用一些限制(例如,security authorize -u foo应该在终端上工作但不能通过ssh工作),但这些没有完全记录,并且从版本更改为版本,因此可能不是你想要依赖的东西。相反,您希望实际读取您的登录会话信息

如果您想更进一步,请先阅读Multiple User Environments Programming Topics。但是有些信息并没有真正记录在任何地方(例如,SessionGetInfo引用的Mach级会话和utmpx引用的BSD级会话如何绑定在一起)。许多相关工具和库都是open source,这可能有所帮助。即使阅读所有内容并没有告诉你如何做你想做的事情,它会告诉你你想要什么,以及用来搜索和提问的正确术语,这可能已经足够了。

答案 1 :(得分:2)

@LevB 的回答很好,但是随着 macOS 中 Python“deprecation”的出现(它还没有从 Big Sur 开始被移除)我想知道是否有另一种获取 CGSSessionScreenIsLocked 的方法,Applecare 企业支持向我指出了 ioreg 这些 CoreGraphics Session 值也存在的地方

下面是一对 shell 函数单行函数,在 shell 样式中,它们在肯定(成功)时返回零 (0),在否定时返回非零 (1),因此它们可以按预期在 {{1 }} 语句。

if

注意这些键​​在屏幕锁定时存在:function screenIsLocked { [ "$(/usr/libexec/PlistBuddy -c "print :IOConsoleUsers:0:CGSSessionScreenIsLocked" /dev/stdin 2>/dev/null <<< "$(ioreg -n Root -d1 -a)")" = "true" ] && return 0 || return 1; } function screenIsUnlocked { [ "$(/usr/libexec/PlistBuddy -c "print :IOConsoleUsers:0:CGSSessionScreenIsLocked" /dev/stdin 2>/dev/null <<< "$(ioreg -n Root -d1 -a)")" != "true" ] && return 0 || return 1; } kCGSSessionSecureInputPIDCGSSessionScreenLockedTime。当屏幕解锁时CGSSessionScreenIsLocked 存在,因此CGSSessionScreenIsLocked比较,因为它永远不会!= "true"

示例用法(因为有时无法实现 "false" 评估退出代码的简单性):

if