Ответ 1
Файл/proc/self/exe является simlink для исполняемого в настоящее время исполняемого файла.
Возможный дубликат:
как найти местоположение исполняемого файла в C
Я хочу, чтобы исполняемый файл мог открыть свой собственный путь; У меня такое чувство, что ответ "вы не можете этого сделать", но я хотел бы, чтобы это было подтверждено!
Я не думаю, что могу использовать getcwd()
, потому что я, возможно, не выполняю его из того же каталога. Я не думаю, что могу использовать argv[0]
, потому что это основано на строке, которая использовалась для ее выполнения. Есть ли другие варианты?
Обоснование
Реальная проблема заключается в том, что я хотел бы разместить исполняемый файл где-нибудь в файловой системе и разместить вместе с ним файл конфигурации по умолчанию. Я хочу, чтобы исполняемый файл мог прочитать его файл конфигурации во время выполнения, но я не хочу жестко указывать это местоположение в исполняемый файл и не хочу, чтобы пользователь должен был устанавливать переменные среды. Если есть лучшее решение этой ситуации, я все уши...
Файл/proc/self/exe является simlink для исполняемого в настоящее время исполняемого файла.
Вы можете использовать getpid() для поиска pid текущего процесса, затем прочитать /proc/<pid>/cmdline
(для читателя) или /proc/<pid>/exe
, который является символической ссылкой на фактическую программу. Затем, используя readlink(), вы можете найти полный путь к программе.
Вот реализация в C:
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
int main()
{
char path[PATH_MAX];
char dest[PATH_MAX];
memset(dest,0,sizeof(dest)); // readlink does not null terminate!
struct stat info;
pid_t pid = getpid();
sprintf(path, "/proc/%d/exe", pid);
if (readlink(path, dest, PATH_MAX) == -1)
perror("readlink");
else {
printf("%s\n", dest);
}
return 0;
}
Если вы хотите попробовать, вы можете скомпилировать это, сделать символическую ссылку из исполняемого файла другим путем и вызвать ссылку:
$ gcc -o mybin source.c
$ ln -s ./mybin /tmp/otherplace
$ /tmp/otherplace
/home/fser/mybin
Используйте файловую систему proc
Ваш поток будет:
/proc/PID/exe
для символической ссылкиНу, вы должны использовать getcwd()
в сочетании с argv[0]
. Первый дает вам рабочий каталог, второй - относительное расположение двоичного файла из рабочего каталога (или абсолютного пути).
Получите свое имя от argv[0]
, затем вызовите команду which
. Это будет работать только в том случае, если ваш исполняемый файл находится в $PATH
.