我正在使用C ++,flex和GNU bison编写一个简单的语言解释器/翻译器。我需要知道可执行文件的路径。对于诸如“mylang mysource.ext”之类的简单情况,我可以使用argc
和argv
来获取路径,但是如果通过shebang调用该文件,我该怎么办(例如“#/ usr / bin /” env mylang“)?
在其他情况下argc
和argv
组合无效。是否可以覆盖这种情况?如果是这样,我想获得可执行文件的完整路径。解决方案必须是跨平台的。如果可能的话,我想避免使用外部库,特别是boost,这对我的目标来说非常大。谢谢!
答案 0 :(得分: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
+ argv[0]
可以正常运行当且仅当您可以保证应用程序中没有任何内容或库从您下面更改当前工作目录(CWD)。 argv[0]
仅在CWD未更改时有效。
此外,如果通过查找la $PATH
的环境变量找到可执行文件,则需要实现路径解析以查找实际位置。 argv[0]
仅返回您的发布方式。即如果你运行命令“ls -al”,argv[0]
命令“ls”将只是“ls”。如果你运行“/ usr / bin / ls -al”,argv[0]
将是“/ usr / bin / ls”。