lis*_*ine 189
总结一下:
在Unix上,/proc真正直接和可行的方法是:
readlink("/proc/self/exe", buf, bufsize) (Linux)的
readlink("/proc/curproc/file", buf, bufsize) (FreeBSD的)
readlink("/proc/self/path/a.out", buf, bufsize) (Solaris)上
在Unix上没有/proc(即如果失败):
如果argv [0]以"/"(绝对路径)开头,则这是路径.
否则,如果argv [0]包含"/"(相对路径),则将其附加到cwd(假设它尚未更改).
否则搜索目录中$PATH的可执行文件argv[0].
之后,检查可执行文件是否实际上不是符号链接可能是合理的.如果是相对于symlink目录解析它.
/ proc方法中不需要此步骤(至少对于Linux).proc符号链接直接指向可执行文件.
请注意,由调用进程argv[0]正确设置.大多数时候都是正确的,但有时候调用进程不可信(例如setuid可执行文件).
在Windows上:使用 GetModuleFileName(NULL, buf, bufsize)
Dal*_*und 17
请注意,以下注释仅限unix.
迂腐这个问题的答案是,没有一般在所有情况下正确地回答这个问题的方式.正如您所发现的那样,父进程可以将argv [0]设置为任何内容,因此无需与程序的实际名称或其在文件系统中的位置有任何关系.
但是,以下启发式通常有效:
/,则用getcwd()确定当前工作目录,然后将argv [0]附加到它.请注意,所有这些都可以通过调用相关程序的过程来规避.最后,您可以使用特定于Linux的技术,例如emg-2提到的技术.其他操作系统可能有相同的技术.
即使假设上面的步骤为您提供了有效的路径名,您仍然可能没有您真正想要的路径名(因为我怀疑您实际想要做的是在某处找到配置文件).硬链接的存在意味着您可以遇到以下情况:
-- assume /app/bin/foo is the actual program
$ mkdir /some/where/else
$ ln /app/bin/foo /some/where/else/foo # create a hard link to foo
$ /some/where/else/foo
Run Code Online (Sandbox Code Playgroud)
现在,上面的方法(包括,我怀疑,/ proc/$ pid/exe)将/some/where/else/foo作为程序的真实路径.而且,事实上,这是该计划的真正途径,而不是您想要的那个.请注意,符号链接不会出现此问题,这在实践中比硬链接更常见.
尽管这种方法原则上不可靠,但在大多数情况下,它在实践中运行良好.
Mic*_*ael 10
实际上不是一个答案,但只是要记住一个注意事项.
正如我们所看到的,在Linux和Unix中找到运行可执行文件的位置的问题非常棘手并且特定于平台.在做这件事之前,应该三思而行.
如果您需要可执行文件的位置,用于发现一些配置或资源文件,也许你应该遵循将文件放置到系统的Unix的方式:把CONFIGS到/etc或/usr/local/etc或在当前用户的主目录,/usr/share是把你的资源文件的好地方.
小智 6
在许多POSIX系统中,您可以检查位于/ proc/PID/exe下的simlink.几个例子:
# file /proc/*/exe
/proc/1001/exe: symbolic link to /usr/bin/distccd
/proc/1023/exe: symbolic link to /usr/sbin/sendmail.sendmail
/proc/1043/exe: symbolic link to /usr/sbin/crond
Run Code Online (Sandbox Code Playgroud)
请记住,在 Unix 系统上,二进制文件可能自启动以来已被删除。它在 Unix 上是完全合法和安全的。最后我检查了 Windows 不允许您删除正在运行的二进制文件。
/proc/self/exe 仍然是可读的,但它实际上不会是一个有效的符号链接。这会……很奇怪。
| 归档时间: |
|
| 查看次数: |
73378 次 |
| 最近记录: |