如何在 OS X 中登录/注销时运行脚本?

如何在 OS X 中登录/注销时运行脚本?

我正在考虑构建一个自定义渲染农场管理器,我想在 OS X 机器不使用时自动将其添加到渲染农场。

有没有办法在任何用户注销后触发脚本运行,然后在任何用户登录后停止?

答案1

在 OS X 中登录/注销时运行脚本的几种方法,有些比较新,只适用于 10.5 及以上版本,有些已经过时了,但最快的方法是添加一个Login Hook

首先,创建要运行的脚本。打开终端并输入:

touch ~/script.sh
open -e !$

这将打开一个文本编辑器。输入脚本,例如以下内容:

#!/bin/sh
# insert your script here

保存文件。在终端中运行:

chmod +x ~/script.sh

这将使文件可执行。现在,让我们将其添加为钩子:

sudo defaults write com.apple.loginwindow LoginHook /usr/local/bin/script.sh 

还有Logout Hook对应物:

sudo defaults write com.apple.loginwindow LogoutHook /usr/local/bin/script2.sh

我已经在 OS X 10.6 上测试过了,应该甚至可以运行到 10.8 版本。请记住,脚本以 运行,root并且分别只有一个用于登录和注销的钩子。

要撤消所有这些,请输入

sudo defaults delete com.apple.loginwindow LoginHook
sudo defaults delete com.apple.loginwindow LogoutHook

请注意,不建议将此方法用于部署或任何用途,但如果您仅像问题所述那样使用它,那应该没有问题。

答案2

在 10.4 中,登录钩子被弃用,取而代之的是 launchd。要在登录时运行脚本,请将这样的 plist 保存为~/Library/LaunchAgents/test.plist。即使您不运行 ,它也会在下次登录时加载launchctl load ~/Library/LaunchAgents/test.plist

<?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>test</string>
    <key>ProgramArguments</key>
    <array>
        <string>say</string>
        <string>test</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

有关详细信息,请参阅man launchd.plist这篇博文

答案3

首选路线是使用苹果的launchd

  • launchd .plist文件可以具有以下键之一:

    #: man launchd.plist
    
    RunAtLoad <boolean>
        This optional key is used to control whether your job is launched once 
        at the time the job is loaded. The default is false. This key should be 
        avoided, as speculative job launches have an adverse effect on system-
        boot and user-login scenarios.
    
    LaunchOnlyOnce <boolean>
        This optional key specifies whether the job can only be run once and 
        only once.  In other words, if the job cannot be safely respawned 
        without a full machine reboot, then set this key to be true.
    
    StartOnMount <boolean>
        This optional key causes the job to be started every time a filesystem 
        is mounted.
    
  • 登录后,launchd将扫描FILES并加载其中定义的守护进程和代理(通过.plist文件)。

    #: man 8 launchd
    FILES
            ~/Library/LaunchAgents         Per-user agents provided by the user.
            /Library/LaunchAgents          Per-user agents provided by the administrator.
            /Library/LaunchDaemons         System-wide daemons provided by the administrator.
            /System/Library/LaunchAgents   Per-user agents provided by Apple.
            /System/Library/LaunchDaemons  System-wide daemons provided by Apple.
    

所以:

  • 关于在登录时运行脚本:

    1. 创建守护进程或代理规范/定义 ( .plist) 文件
    2. 使用RunAtLoad .plist密钥,也可以使用LaunchOnlyOnce
    • 如果你希望在挂载特定磁盘映像/卷/文件系统时专门运行,则可以使用StartOnMount
    1. 将文件放在适当的目录.plistFILES

    现在launchd将在登录时自动加载并根据您的规范/定义运行它。

  • 关于在注销时运行脚本:您可以尝试在登录时运行注销内容,但除此之外,我不知道有什么键具有在注销时触发守护进程/代理的功能,但是您可以尝试找到在注销时发生的事件,该事件launchd可以检测并将其用作守护进程/代理规范/定义的触发器。

    • launchd.plist有一个名为的键Sockets,也许有办法用它

答案4

为了使这些钩子在 10.10 中发挥作用,你需要执行以下操作:

  1. 打开/etc/ttys文件:在 Finder 中,从前往菜单中选择前往文件夹,输入/etc/,然后单击前往。

  2. 在出现的窗口中,ttys使用您喜欢的文本编辑器(例如 TextEdit)打开该文件。

  3. 查找以下行:

    console "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow" vt100 on secure window=/System/Library/CoreServices/WindowServer onoption="/usr/libexec/getty std.9600"

  4. 编辑此行,使其内容如下(此行没有中断):

    console "/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow -LoginHook /path/to/script" vt100 on secure window=/System/Library/CoreServices/WindowServer onoption="/usr/libexec/getty std.9600"

    即添加(其中-LoginHook /path/to/script/path/to/script是用户登录时要执行的脚本的完整路径),就在第二个引号 ( ") 标记之前。

  5. 保存文件。

确保用于编辑此文件的文本编辑器不会将上面的行拆分成多行。


或按照此处的完整说明进行操作:

http://support.apple.com/en-ca/HT2420

相关内容