在 mac 中制作登录/注销脚本

问题描述 投票:0回答:1

我有一个 shell 脚本,我想在登录和注销时运行它。

是这样的

#!/bin/bash

# Define the log file path
LOG_FILE="/Users/kamabokogonpachiro/Desktop/logfile.log"

# Function to log login
log_login() {
    echo "$(date) - User $1 logged in" >> "$LOG_FILE"
}

# Function to log logout
log_logout() {
    echo "$(date) - User $1 logged out" >> "$LOG_FILE"
}

# Check if the script is called with a username argument
if [ "$1" ]; then
    # If the script is called with "logout" as the first argument, log the logout
    if [ "$1" = "logout" ]; then
        log_logout "$2"
    else
        # Otherwise, log the login
        log_login "$1"
    fi
fi

登录脚本保存在

~/Library/LaunchAgents/com.user.login.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>com.user.login.sh</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/kamabokogonpachiro/Desktop/logfile.sh</string>
        <string>login</string>
        <string>$(whoami)</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WorkingDirectory</key>
    <string>/Users/kamabokogonpachiro/Desktop</string>
</dict>
</plist>

同样,注销脚本位于

~/Library/LogoutAgents/com.user.logout.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>com.user.logout</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/kamabokogonpachiro/Desktop/logfile.sh</string>
        <string>logout</string>
        <string>username</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

我也做了

launchctl load ...

尽管如此,它们仍然无法工作,shell 脚本也被标记为可执行。我不知道我错过了什么。我的做法不正确吗?还有更好的方法吗?我尝试过使用

last
,但 BSD 与
Linux (GNU)
不同,而且用途不那么广泛。

bash macos shell plist
1个回答
0
投票

我认为您不能在

$(whoami)
文件中使用像命令替换
.plist
这样的 shell 设施;它只会作为文字字符串传入,就像您在 shell 中在它周围写了单引号一样。

如果第一个参数是

whoami
,只需重构脚本即可运行
login
;或者也许简单地使用系统已经设置的
$USER

您似乎还忘记在

Program
文件中包含
.plist
键。我不知道 Bash 是否关心,但我会添加它以防万一。

顺便说一下,在用户的

Desktop
目录中执行这些操作很奇怪。可能会在用户的主目录中创建一个隐藏文件;如果用户愿意,可以在桌面上创建指向它的符号链接。我同样将二进制文件的位置更改为下面的
bin
中。

<?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>com.user.login.sh</string>
    <key>Program</key>
        <string>/bin/bash</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/kamabokogonpachiro/bin/logfile.sh</string>
        <string>login</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WorkingDirectory</key>
    <string>/Users/kamabokogonpachiro</string>
</dict>
</plist>

另请参阅https://apple.stackexchange.com/questions/110644/getting-launchd-to-read-program-arguments- Correctly

此外,不要对私有变量使用大写。

#!/bin/bash

# Define the log file path
logfile="~/.logfile.log"

log_login() {
    echo "$(date) - User $USER logged in" >> "$logfile"
}

log_logout() {
    echo "$(date) - User $USER logged out" >> "$logfile"
}

case $1 in
    login) log_login;;
    logout) log_logout;;
esac
© www.soinside.com 2019 - 2024. All rights reserved.