请求用户的“root”访问权限以更新“/etc/paths.d”

requesting `root` access from user to update `/etc/paths.d`

我的应用程序安装程序使用标准的开放式 DMG,拖到 'Applications' 进行安装,但我想更新 $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 进行排序,我希望我会知道从哪里开始。

AuthorizationExecuteWithPrivileges is deprecated for a long time, but still present and working in macOS 11 (Big Sur / 10.16). STPrivilegedTask 演示了如何以“安全”的方式调用函数——也就是说,正确处理函数可能在 OS 的未来版本中被删除的情况。

用法是这样的(为简洁起见省略了错误检查等)。这将在 /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 一样将它放在菜单项(“安装命令行工具”)后面。如果您想在启动时安装它,我建议先提示用户(并允许他们选择“不再询问我”)。