可执行文件可以发现自己的路径吗?(Linux)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4025370/
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-04 23:47:39  来源:igfitidea点击:

Can an executable discover its own path? (Linux)

clinux

提问by Oliver Charlesworth

Possible Duplicate:
how to find the location of the executable in C

可能的重复:
如何在 C 中找到可执行文件的位置

I would like an executable to be able to discover its own path; I have a feeling that the answer is "you can't do this", but I would like this to be confirmed!

我希望一个可执行文件能够发现它自己的路径;我有一种感觉,答案是“你不能这样做”,但我希望这一点得到证实!

I don't think I can use getcwd(), because I might not be executing it from the same directory. I don't think I can use argv[0], because that is based on the string that's used to execute it. Are there any other options?

我不认为我可以使用getcwd(),因为我可能不会从同一目录执行它。我不认为我可以使用argv[0],因为这是基于用于执行它的字符串。还有其他选择吗?

Rationale

基本原理

The real problem is that I'd like to place an executable somewhere on a filesystem, and place a default config file alongside it. I want the executable to be able to read its config file at runtime, but I don't want to hardcode this location into the executable, nor do I want the user to have to set environment variables. If there's a better solution to this situation, I'm all ears...

真正的问题是我想在文件系统的某个地方放置一个可执行文件,并在它旁边放置一个默认配置文件。我希望可执行文件能够在运行时读取其配置文件,但我不想将此位置硬编码到可执行文件中,也不希望用户必须设置环境变量。如果有更好的解决方案来解决这种情况,我会全神贯注......

采纳答案by Cercerilla

The file /proc/self/exe is a simlink to the currently running executable.

文件 /proc/self/exe 是当前运行的可执行文件的模拟链接。

回答by ?imon Tóth

Well, you have to use getcwd()in conjuction with argv[0]. The first one gives you the working directory, the second one gives you the relative location of the binary from the working directory (or an absolute path).

好吧,您必须getcwd()argv[0]. 第一个为您提供工作目录,第二个为您提供工作目录中二进制文件的相对位置(或绝对路径)。

回答by NG.

Use the proc filesystem

使用proc 文件系统

Your flow would be:

你的流程是:

  • Get pid of executable
  • look at /proc/PID/exefor a symlink
  • 获取可执行文件的pid
  • 寻找/proc/PID/exe符号链接

回答by Aif

Edit:It was pointed out that using /proc/self/exeis more straightforward. That is entirely true, but I didn't see any benefit in editing the code. Since I still get comments about it, I've edited it.

编辑:有人指出使用/proc/self/exe更直接。这是完全正确的,但我没有看到编辑代码有任何好处。由于我仍然收到有关它的评论,因此我对其进行了编辑。

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

int main()
{
  char dest[PATH_MAX];
  memset(dest,0,sizeof(dest)); // readlink does not null terminate!
  if (readlink("/proc/self/exe", dest, PATH_MAX) == -1) {
    perror("readlink");
  } else {
    printf("%s\n", dest);
  }
  return 0;
}

Initial answer:You can use getpid() to find the pid of the current process, then read /proc/<pid>/cmdline(for a human reader) or /proc/<pid>/exewhich is a symlink to the actual program. Then, using readlink(), you can find the full path of the program.

初始答案:您可以使用 getpid() 来查找当前进程的 pid,然后读取/proc/<pid>/cmdline(对于人类读者)或/proc/<pid>/exe它是实际程序的符号链接。然后,使用 readlink(),您可以找到程序的完整路径。

Here is an implementation in C:

这是在 C 中的实现:

#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>

int main()
{
  char path[PATH_MAX];
  char dest[PATH_MAX];
  memset(dest,0,sizeof(dest)); // readlink does not null terminate!
  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;
}

If you want to try, you can then compile this, make a symlink from the executable to an other path, and call the link:

如果你想尝试,你可以编译它,创建一个从可执行文件到另一个路径的符号链接,然后调用链接:

$ gcc -o mybin source.c
$ ln -s ./mybin /tmp/otherplace
$ /tmp/otherplace
/home/fser/mybin

回答by Gaius

Get your name from argv[0]then call out to the whichcommand. This will obv only work if your executable is in $PATH.

从那里得到你的名字,argv[0]然后呼唤which命令。仅当您的可执行文件位于$PATH.