【问题标题】:Get bash $PATH from C++ program从 C++ 程序中获取 bash $PATH
【发布时间】:2021-11-01 21:28:16
【问题描述】:

在终端应用程序中,我的$PATH 是:

/usr/local/opt/python/libexec/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin

如果用户使用 Dock 启动我的 C++ 应用程序,它的 $PATH 是:

/usr/bin:/bin:/usr/sbin:/sbin

我希望我的应用程序始终具有与终端 (bash) 相同的 $PATH。 有没有简单的方法来实现这一点?

我现在知道的唯一方法是在磁盘上创建一个带有 echo $PATH 之类的 bash 脚本,使用 bash -l 命令从我的 C++ 程序启动它,读取输出并更新我的进程'@ 987654328@ 相应变量。

而且,我不想以任何方式更改用户系统的配置。这应该无需用户进行任何额外操作即可工作,并且不会以任何方式影响用户的系统。

【问题讨论】:

  • 这当然是一种合理的做法。来自 Bare Bones Software 的 BBEdit 正是这样做的。我提醒您不要假设用户的首选 shell 实际上是 bash,而是您阅读了他们的默认 shell 并使用它。
  • 您必须让您的应用确定用户使用的外壳,然后调用它或解释它的启动文件。
  • 我不得不说,你不想尝试自己解释启动文件。这就是外壳的用途。 ^_^ 只需启动一个非交互式登录 shell 并读取它的环境。我知道 BBEdit 这样做是因为 v14 没有在 Unix Worksheets 中正确设置路径,我询问了他们的技术支持他们如何确定路径,然后让他们将 ksh 添加到他们的 shell 列表中。引用:“BBEdit 永远不会设置 $PATH;当它启动时,它将启动一个非交互式登录 shell 并运行 printenv 命令,并解释输出以找到 PATH。”
  • 关于bash 不是默认外壳的问题...询问bash my $PATH 或多或少没用。您不能假设用户的 shell 是 bash,或者如果不是,他们已经投入任何精力来配置 bash
  • @MarcWilson 在 macOS 上,/etc/passwd 是一个不包含任何有用内容的存根。实际帐户作为 .plist 文件存储在 /var/db/dslocal/nodes/Default/users/ 中。或者可能在网络域或其他地方。 dscl 是获取用户信息的好方法。

标签: c++


【解决方案1】:

如果您不喜欢调用 bash 的解决方案,这里有一个存根,可以对调用 shell 进行更多控制,并可能在 c++ 程序中测试用户默认 shell 是否不是 bash

setenv("PATH", "/MyCustomPath:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin", 1);

读取 bash 的路径:

std::string exec(const char* cmd) {
    char buffer[128];
    std::string result = "";
    FILE* pipe = popen(cmd, "r");
    if (!pipe) throw std::runtime_error("popen() failed!");
    try {
        while (fgets(buffer, sizeof buffer, pipe) != NULL) {
            result += buffer;
        }
    } catch (...) {
        pclose(pipe);
        throw;
    }
    pclose(pipe);
    return result;
}

setenv("PATH", exec("bash -l -c 'echo -n $PATH'").c_str(), 1);

【讨论】:

  • 您确定问题是关于如何设置 PATH 环境变量?在回答问题之前先阅读和理解问题很有用。 :)
  • 每个程序都选择自己的环境变量或从父进程继承。为确保您的程序始终具有与 bash 相同的路径,程序本身必须调用 SETENV。如果需要,该程序可以读取和设置 bash 的配置文件。
  • 没有通过任何 C++ 代码审查(该代码与字符 std:: 纯 C 代码不同,没有使用任何 C++ 改进。
  • @mmmmmm 也许代码不好(我不在乎,我在写我自己的,而不仅仅是复制/粘贴),但现在它包含了一些对我非常有用的信息。例如。我不知道如何在磁盘上没有脚本文件的情况下运行 shell 脚本。 :) 是的,我是 Unix 的新手 :)
  • Bash 在交互调用时表现不同。如果这是你想要的,也许可以添加一个 -i 标志来强制它是交互式的。
【解决方案2】:

在许多情况下,从 Shell/Explorer/Dock/etc 启动应用程序会获得与命令行/终端/bash 不同的环境,因为 GUI 登录过程而不是命令行/终端调用的是 Shell/Explorer/Dock /重击。

当您运行 Terminal/Bash 时,.bashrc/.bash_profile 等脚本会运行,这些脚本通常配置为向 PATH 环境变量添加内容以方便命令行。

从这个问题中并不清楚您的应用程序是否会被其他用户或您自己使用:

  1. 您能否将“Dock Icon”更改为指向在启动 C++ 应用程序之前设置 PATH 环境变量的 Shell 脚本?

  2. 如果它只适合你,你可以破解你的系统范围的 bashrc:sudo $EDITOR /etc/bashrc ..但不建议这样做

  3. 如果您的 C++ 应用程序依赖于 $PATH 中的某些内容,您可以围绕它编写代码吗?例如,使用您需要运行的任何应用程序的绝对路径。

【讨论】:

    猜你喜欢
    • 2010-12-02
    • 1970-01-01
    • 2014-06-21
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多