【问题标题】:requesting `root` access from user to update `/etc/paths.d`请求用户的“root”访问权限以更新“/etc/paths.d”
【发布时间】:2026-02-12 07:40:01
【问题描述】:

我的应用安装程序使用标准的打开 DMG,拖到“应用程序”进行安装,但我想更新 $PATH 以便可以从命令行使用我的应用。

我认为正确的方法是在我的应用程序第一次运行时调用一个脚本,该脚本在/etc/paths.d 中创建一个文件myapp,其文本为/Applications/myapp/bin,后跟一个换行符(ascii 13):

rm /etc/paths.d/myapp
echo "/Applications/myapp/bin" > /etc/paths.d/myapp

目前我遇到了错误;

rm: /etc/paths.d/myapp: No such file or directory
./myapp.sh: line 2: /etc/paths.d/myapp: Permission denied

我需要触发用户输入管理员密码的请求,但我不确定如何以一种清楚地告知用户我正在对其系统进行哪些更改的方式执行此操作以及为什么。 (我可以将其添加到手册中,但谁会阅读)

有什么建议吗?

PS 我需要在 linux(希望类似)和 Windows 上做同样的事情,但如果我可以对 MacOS 进行排序,希望我会知道从哪里开始。

【问题讨论】:

  • 让我知道我是否可以在 cmets 中改进这个问题
  • 我想我需要做类似sudo rm /etc/paths.d/myapp echo "/Applications/myapp/bin" > /etc/paths.d/myapp
  • 您当前的问题似乎是获取 root 访问权限。阅读标题时不清楚。也许你可以改进它。
  • 谢谢@Itchy 我改了标题。

标签: macos installation config macos-catalina


【解决方案1】:

AuthorizationExecuteWithPrivileges 已被弃用很长时间,但在 macOS 11 (Big Sur / 10.16) 中仍然存在并工作。 STPrivilegedTask 演示了如何以“安全”的方式调用函数 - 即正确处理可能在未来版本的操作系统中删除函数的情况。

用法是这样的(为简洁起见,省略了错误检查等)。这将在 /usr/local/bin 中创建一个名为“my-app”的可执行文件的符号链接:

    AuthorizationRef authorizationRef;
    OSStatus err;

    const char* tool = "/bin/ln";
    char *args[] = {
        "-sf", 
        [[[NSBundle mainBundle] executablePath] UTF8String],
        "/usr/local/bin/my-app", 
        nil
    };

    AuthorizationCreate(nil, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);

    err = AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, nil);

    switch (err)
    {
        case errAuthorizationCanceled:
            // user cancelled prompt
            break;
        case errAuthorizationSuccess:
            // success
            break;
        default:
            // an error occurred
            break;
    }

    AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);

你如何使用它,取决于你——你可以像 cmake 那样把它放在一个菜单项(“安装命令行工具”)后面。如果您想在启动时安装它,我建议先提示用户(并允许他们选择“不要再问我”)。

【讨论】: