CWD 和文件路径字符串在 launchctl 调用中自动连接

CWD 和文件路径字符串在 launchctl 调用中自动连接

我目前正在尝试为我的函数编写一个函数bash 配置文件这会导致作为参数传递的 OSX LaunchAgent 重新启动。这可能有点毫无意义,但对于我来说,我不想再为它编写长路径launchctl un/load

除了对 launchctl 的最后调用之外,我几乎已经完成了所有工作。这是函数脚本和随后的错误消息:

功能

launchctl_mgr() {
        failure() {
                local lineno=$1
                local msg=$2
                echo "Failed at $lineno: $msg"
        }
        trap 'failure ${lineno} "$BASH_COMMAND"' ERR
        trap 'trap - ERR' RETURN

        instruction=$1
        filepath=$2;
        #test whether the file argument is already a file or not and whether or not it is actually$
        if [[ ! -f $2 ]]
        then
                if [[ -f ~/Library/LaunchAgents/$2.plist ]]
                then
                        filepath="~/Library/Launchagents/$filepath.plist"
                        echo "found!: $filepath"
                elif [[ -f /Library/LaunchAgents/$2.plist ]]
                then
                        filepath="/Library/LaunchAgents/$filepath.plist"
                else
                        echo "debug: ~/Library/LaunchAgents/$filepath.plist"
                        echo "Filename supplied was not valid as a launchagent"
                        return 1
                fi
        fi
        if [[ $instruction=="restart" || instruction=="unload" ]]
        then
                echo "instruction is $instruction"
                echo "filepath is $filepath"
                launchctl stop $filepath
                launchctl unload $filepath
                if [[ instruction=="restart" ]]
                then
                        launchctl load $filepath
                        launchctl start $filepath
                fi
        fi
}

输出/错误

____________________ => launchctl_mgr unload local.unminimise
found!: ~/Library/Launchagents/local.unminimise.plist
instruction is unload
filepath is ~/Library/Launchagents/local.unminimise.plist
Failed at launchctl stop $filepath:
/Users/[current_user]/~/Library/Launchagents/local.unminimise.plist: No such file or directory
/Users/[current_user]/~/Library/Launchagents/local.unminimise.plist: No such file or directory
Failed at launchctl start $filepath:

(“[current_user]”替换我的实际用户帐户名)

正如您在 launchctl 中看到的,无论是 bash 还是 launchctl,当前目录路径和我输入 launchctl 的路径字符串都连接在一起,从而导致错误。文件路径字符串被打印出来并且在之前的行中看起来没问题

答案1

  1. 在 [[ ... ]] 测试中,您需要在 == 之前和之后有空格,否则它们只会被评估为字符串,并且非空始终为真。

    例如:

    $ instruction=whatever
    $ [[ $instruction=="restart" ]] && echo true || echo false
    true
    

    这相当于:

    $ [[ whatever=="restart" ]] && echo true || echo false
    true
    

    它也相当于以下内容(以及其他几个变体):

    $ [[ -n 'whatever=="restart"' ]] && echo true || echo false
    true
    

    在所有这些情况下,您都不会检查是否$instruction等于“重新启动”。相反,您正在测试字符串是否whatever=="restart"非空。该字符串恰好包含字符序列==,但这并不重要。它们只是嵌入字符串中的字符,没有特殊含义。

    与之比较:

    $ instruction=whatever
    $ [[ $instruction == "restart" ]] && echo true || echo false
    false
    $ instruction=restart
    $ [[ $instruction == "restart" ]] && echo true || echo false
    true
    

  1. 脚本中还有一些地方$缺少 before 变量。例如

    if [[ $instruction=="restart" || instruction=="unload" ]]
    

    这需要前后空格== a$在第二个之前instruction

    if [[ $instruction == "restart" || $instruction == "unload" ]]
    

    同样在这里:

    if [[ instruction=="restart" ]]
    

    那应该是:

    if [[ $instruction == "restart" ]]
    

  1. 使用变量(和 shell 位置参数)时需要用双引号引起来。例如

    local lineno="$1"
    local msg="$2"
    

    和:

    instruction="$1"
    filepath="$2"
    

    和:

    launchctl stop "$filepath"
    launchctl unload "$filepath"
    

  1. 为什么要把它写成一个函数而不是一个独立的脚本?您需要它来更改当前 shell 的环境吗?

    编写函数没有什么问题,但除非你如果要更改当前 shell 的环境,您最好使用单独脚本提供的隔离,这样您就不会意外更改环境。

    或声明全部你的函数变量(包括$instruction$filepathlocal但是这只适用于防止变量被改变,函数仍然可以改变其他东西,比如shell的当前目录。

答案2

非常感谢 Cas 的回答和 bash 语法方面的帮助,但我从一些修补中发现波形符in~/Library/LaunchAgents/[agent]是导致脚本实际按预期工作而不是抛出串联路径的问题的原因。

由于某种原因,波形符不会在 launchctl 地址参数中展开,因此如果其他人遇到此问题,请使用:

$HOME/Library/LaunchAgents/[agent]

在 launchctl 命令中寻址您的代理。

该路径如所描述的这里在下面“旧命令”然后“加载”

注意:对于我的脚本来说,至少这实际上并没有解决 launchctl 抛出错误,但确实修复了功能。尽管文档说:

由于先前实现中的错误以及客户对这些错误的长期期望,由于使用不当,加载和卸载子命令只会返回非零退出代码。否则,始终返回零。

..我设置的 ERR 陷阱始终会抛出错误而没有消息,即使脚本按预期工作并且手动复制命令不会给出任何错误消息。

也许有人可以弥补我的无知,但如果您在我的建议后仍然感到头疼,请尝试launchctl list | grep [agent_name]看看是否达到了预期的效果

相关内容