如何从内部找到C++ Linux程序的完整路径?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7051844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 05:42:15  来源:igfitidea点击:

How to find the full path of the C++ Linux program from within?

c++linux

提问by Sharath

I have this requirement where I need to find the full path for the C++ program from within. For Windows, I have the following solution. The argv[0] may or may not contain the full path. But I need to be certain.

我有这个要求,我需要从内部找到 C++ 程序的完整路径。对于 Windows,我有以下解决方案。argv[0] 可能包含也可能不包含完整路径。但我需要确定。

TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], base[_MAX_FNAME], ext[_MAX_EXT];
TCHAR fullPath[255+1];
_splitpath(argv[0],drive,dir,base,ext);
SearchPath(NULL,base,ext,255,fullPath,NULL);

What is the Linux (gcc) equivalent for the above code? Would love to see a portable code.

上面代码的 Linux (gcc) 等价物是什么?很想看到一个可移植的代码。

采纳答案by Kerrek SB

On Linux (Posix?) you have a symbolic link /proc/self/exewhich links to the full path of the executable.

在 Linux (Posix?) 上,您有一个符号链接/proc/self/exe,它链接到可执行文件的完整路径。

On Windows, use GetModuleFileName.

在 Windows 上,使用GetModuleFileName.

Never rely on argv[0], which is not guaranteed to be anything useful.

永远不要依赖argv[0],这不能保证有任何用处。

Note that paths and file systems are not part of the language and thus necessarily a platform-dependent feature.

请注意,路径和文件系统不是语言的一部分,因此必然是依赖于平台的功能。

回答by olooney

The top answer to this question lists techniques for a whole bunch of OSes:

这个问题的最佳答案列出了一大堆操作系统的技术:

Finding current executable's path without /proc/self/exe

在没有 /proc/self/exe 的情况下查找当前可执行文件的路径

回答by MetallicPriest

string get_path( )
{
        char arg1[20];
        char exepath[PATH_MAX + 1] = {0};

        sprintf( arg1, "/proc/%d/exe", getpid() );
        readlink( arg1, exepath, 1024 );
        return string( exepath );
}

回答by ETech

For Linux:
Function to execute system command

对于 Linux:
执行系统命令的函数

int syscommand(string aCommand, string & result) {
    FILE * f;
    if ( !(f = popen( aCommand.c_str(), "r" )) ) {
            cout << "Can not open file" << endl;
            return NEGATIVE_ANSWER;
        }
        const int BUFSIZE = 4096;
        char buf[ BUFSIZE ];
        if (fgets(buf,BUFSIZE,f)!=NULL) {
            result = buf;
        }
        pclose( f );
        return POSITIVE_ANSWER;
    }

Then we get app name

然后我们得到应用名称

string getBundleName () {
    pid_t procpid = getpid();
    stringstream toCom;
    toCom << "cat /proc/" << procpid << "/comm";
    string fRes="";
    syscommand(toCom.str(),fRes);
    size_t last_pos = fRes.find_last_not_of(" \n\r\t") + 1;
    if (last_pos != string::npos) {
        fRes.erase(last_pos);
    }
    return fRes;
}

Then we extract application path

然后我们提取应用程序路径

    string getBundlePath () {
    pid_t procpid = getpid();
    string appName = getBundleName();
    stringstream command;
    command <<  "readlink /proc/" << procpid << "/exe | sed \"s/\(\/" << appName << "\)$//\"";
    string fRes;
    syscommand(command.str(),fRes);
    return fRes;
    }

Do not forget to trim the line after

之后不要忘记修剪线

回答by user541686

If you came here when Googling for GetModuleFileName Linux... you're probably looking for the ability to do this for dynamically-loaded libraries. This is how you do it:

如果你在谷歌搜索时来到这里GetModuleFileName Linux......你可能正在寻找为动态加载的库执行此操作的能力。这是你如何做到的:

struct link_map *lm;
dlinfo(module, RTLD_DI_LINKMAP, &lm);
lm->l_name  // use this

回答by suspic

#include <string>
#include <unistd.h>
#include <limits.h>

std::string getApplicationDirectory() {
    char result[ PATH_MAX ];
    ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
    std::string appPath = std::string( result, (count > 0) ? count : 0 );

    std::size_t found = appPath.find_last_of("/\");
    return appPath.substr(0,found);
}