【问题标题】:How to find an exe in $PATH using Boost如何使用 Boost 在 $PATH 中查找 exe
【发布时间】:2016-08-12 10:14:51
【问题描述】:

我正在使用 Boost 库编写 C++ 程序。我需要能够找到可执行文件的完整路径,仅给出名称。这相当于 Unix shell 的 which 实用程序、Windows 的 where 或 Python 的 shutil.which

有没有办法做到这一点?我当然可以通过迭代 PATH 环境变量来编写自己的代码,但是为了可移植性,我需要考虑拆分 :; 等,以及是否有预先编写的(并经过测试! ) 例程我更喜欢使用它。

【问题讨论】:

  • 好吧,最终你将需要考虑你所使用的 shell 的细节,所以你为什么不直接使用那个 shell 提供的工具 boggle

标签: c++ boost


【解决方案1】:

在 boost 中没有任何东西可以直接实现这一点。你可以:

  1. getenv()读取PATH的内容,使用Boost File System以可移植的方式处理路径,并手动处理多路径拆分-似乎拆分字符的数量不会很疯狂,只有几种选择
  2. invoke 你的 shell 现有的 which 程序(或其变体)
  3. 调用一个简单的python程序调用shutil.which,例如system("python -c \"import shutil; shutil.which('ls');\"")

【讨论】:

  • 好的,很公平。有点遗憾,没有可用的东西,但正如你所说,自己写它并不是一场灾难。我不想开始炮轰其他程序,因为我用 C++ 编写这个应用程序的原因是性能和低占用空间,调用子进程会杀死它(那时我可能还不如把整个事情写在Python 无论如何...)
  • 嗯,好的。从性能 POV 来看,用 C++ 编写这种类型的东西可能有点矫枉过正;也有点适得其反; python 对系统级任务恕我直言有更好的支持。我不知道你的上下文,但你大概可以在程序启动时加载所有路径信息,这在任何语言中都需要很少的时间
【解决方案2】:

“写我自己的”是典型的做法。虽然这在 C 中可能是一个熊,但对于 C++ 及其丰富的std::string 类,这变得很容易。甚至不需要Boost。这将是 C++ 入门课程中的典型家庭作业:

std::string s=getenv("PATH");

const char sep=':';  // Or use ';', if you feel like it.

auto b=s.begin(), e=s.end();

while (b != e)
{
    if (*b == sep)
    {
        ++b;
        continue;
    }

    auto p=b;
    b=std::find(b, e, sep);

    auto check=std::string(p, b) + "/" + filename;

    if (access(filename.c_str(), X_OK) == 0)
    {
          // Found it. Insert code here.
    }
}

这是一个无关紧要的问题,将其删除可能会更快,然后尝试在某个地方找到一些库函数,它可以做同样的事情。

【讨论】:

  • 当然,除了这种类型的代码在使用文件系统时不是完全可移植的:auto check=std::string(p, b) + "/" + filename;(即硬编码的/)并且是你自己做的错误类型恕我直言; OP 不是在问怎么做,而是在问如何以便携的方式来做,我认为这是有道理的;
  • 另外,std::string 至少在 Windows 上不支持文件系统支持的完整 Unicode 字符集。所以便携式版本需要进行编码转换,或者使用 wstring。基本上,在“为我工作”的情况下,它已经足够简单了,对于需要为很多用户工作的东西来说,它就不是那么简单了......
猜你喜欢
  • 2012-03-02
  • 2011-11-07
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
  • 2016-05-29
  • 2017-04-16
  • 2018-07-14
  • 2019-08-18
相关资源
最近更新 更多