Как найти полный путь к программе С++ Linux изнутри?
У меня есть это требование, когда мне нужно найти полный путь для программы на С++ изнутри. Для 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);
Что такое эквивалент Linux (gcc) для вышеуказанного кода? Хотелось бы увидеть портативный код.
Ответы
Ответ 1
В Linux (Posix?) у вас есть символическая ссылка /proc/self/exe
, которая ссылается на полный путь исполняемого файла.
В Windows используйте GetModuleFileName
.
Никогда не полагайтесь на argv[0]
, что не гарантируется ничем полезным.
Обратите внимание, что пути и файловые системы не являются частью языка и, следовательно, обязательно зависят от платформы.
Ответ 2
В верхнем ответе на этот вопрос перечислены методы для целого ряда ОС:
Поиск текущего пути исполняемого файла без/proc/self/exe
Ответ 3
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 );
}
Ответ 4
Для 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;
}
Затем мы получим имя приложения
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;
}
Затем мы извлекаем путь приложения
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;
}
Не забывайте обрезать линию после
Ответ 5
#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);
}
Ответ 6
Если вы пришли сюда, когда Googling для GetModuleFileName Linux
... вы, вероятно, ищете возможность сделать это для динамически загружаемых библиотек. Вот как вы это делаете:
struct link_map *lm;
dlinfo(module, RTLD_DI_LINKMAP, &lm);
lm->l_name // use this