1

我正在使用 C++、flex 和 GNU bison 编写一个简单的语言解释器/翻译器。我需要知道可执行文件的路径。对于诸如“mylang mysource.ext”之类的简单情况,我可以使用argcand获取路径argv,但是如果通过 shebang 调用文件(例如“#/usr/bin/env mylang”),我该怎么办?

在其他情况下argcargv组合不起作用。是否有可能覆盖这种情况?如果是这样,我想获得可执行文件的完整路径。解决方案必须是跨平台的。如果可能的话,我想避免使用外部库,尤其是 boost,这对我的目标来说非常大。谢谢!

4

1 回答 1

0

这将非常依赖于平台,但对于 linux,符号链接“/proc/self/exe”指向当前映像的物理路径。从这里,您可以使用 readlink 来确定路径。我最近使用了这个:

#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string>
#include <stdexcept>
#include <boost/scoped_array.hpp>

std::string path;

size_t size = 1024;
const ssize_t err = static_cast<ssize_t>(-1);
while (true)
{
    boost::scoped_array<char> buffer(new char[size]);

    ssize_t res = readlink("/proc/self/exe", buffer.get(), size);

    if (res == err)
    {
        if (errno == ENAMETOOLONG)
            size *= 2; // try again
        else
            throw std::runtime_error("unexpected error during readlink");
    }
    else
    {
        path.assign(buffer.get(), res);
        break;
    }
}

这是使用 G++ 4.1.2 完成的,因此不可unique_ptr用,也可以轻松删除对boost::scoped_array.

注意:这为您提供了当前图像的完整路径,而不是图像所在的目录。要获取目录,您需要进行一些操作。Boost Filesystem 也有一些很好的功能来做到这一点。否则,您将不得不自己解析它。

此外,如果您是库,并且不能依赖另一部分代码更改当前工作目录,或者无权访问argv. getcwd+当且仅当您可以保证您的应用程序或库中的任何内容都不会从您下方更改当前工作目录(CWD)时, +argv[0]才能正常工作。仅当 CWD 不变时才有效。argv[0]

此外,如果可执行文件是通过环境变量查找 la 定位的$PATH,则您需要实现路径解析以找到您的真实位置。argv[0]仅返回您的启动方式。即,如果您运行命令“ls -al”,argv[0]则命令“ls”将只是“ls”。如果您运行“/usr/bin/ls -al”,argv[0]将是“/usr/bin/ls”。

于 2013-04-04T00:38:20.960 回答