在*nix系统的C中,找到$ PATH或"which"的二进制绝对路径?

jmn*_*ben 1 c linux

我想要获得二进制的绝对路径(特别是7zip的7z).我认为这可以通过任何一种方式完成

  1. 获取$ PATH环境变量,并检查每个目录中是否存在7z,或者

  2. "炮轰"到哪个命令并从其标准中读取.

哪种方法最常规?

Bas*_*tch 5

第一种方法(使用getenv("PATH")和扫描它......)是更好和更有效的...这通常是which 通常做的(但不依赖于which谁的行为可以变化很多......)但你不会分叉(2)任何过程(和forksystemwhich可能失败).

但是,我怀疑为什么你需要找到一些可执行文件的路径.在执行该程序时,你可以简单地使用execvp(3)(和类似的exec*p*函数,所有这些函数都相同getenv("PATH"),然后像在execve(2)之前一样在内部进行扫描).

(在非常病态的情况下,你可以忽略,getenv("PATH")可能会失败)

请注意,二进制可执行文件可以在您测试其存在(并在其中找到PATH)和您执行它的那一刻(2)之间被删除(或添加或损坏...).而且execve由于许多原因(很少)可能会失败(或很少),或者没有按预期工作(特别是,如果您的7z可执行文件所依赖的某些共享库已损坏或被删除).

不要忘记,在Linux上,有几个进程可以读取和写入(或执行)同一个文件(在读取时也可以删除重命名).请阅读有关i节点的更多信息.

因此,找到7z之前的完整路径execvp是错误的 - 或者是不准确的:7z在路径检查之后和其执行之前, 某些其他程序可能已经移除或重新安装(2).我不明白你为什么要扫描它PATH,我相信它通常是无用的,留下来execvp

另见wordexp(3),glob(3),glob(7)

由于Linux发行版上的大多数软件都是免费软件,因此您可以(也许您应该)研究它们的源代码.对于which它往往是你的shell的内置(和bash,zsh,fish都是免费软件),或从程序中的debianutils(也许不是coreutils的),我不知道,大多数分布有它(其中有些会不安装它默认情况下).

PS.我的感觉是你的代码不应该使用7z通常在大多数Linux系统上都不可用 - 而不是在我的系统上; 您可能隐含地要求您的用户安装它(至少文档).您可能更喜欢tar归档zip,注意tar.h是POSIX标题!看到这个问题并考虑一下libtar