如何检查命令是否可用或存在?

3

我正在Linux上用C语言开发一个控制台应用程序。

现在它的一个可选部分(不是必须的)依赖于一个命令/二进制文件是否可用。

如果我使用system()检查,我会得到sh: command not found作为不想要的输出,并且它将其检测为存在。那么我该如何检查命令是否存在?


这不是从Bash脚本中检查程序是否存在的重复问题,因为我正在使用C,而不是BASH。


你传递给 system() 的是什么? - arunkumar
我正在使用版本选项传递程序名称,例如 system("ls --version")。至少这是我的想法。 - Cobra_Fast
1
在安装时检查所有依赖命令/软件包版本是否存在,这样不是更有意义吗?如果在编译/安装应用程序时它们已经存在,那么你可以合理地假设它们在运行时也存在。如果你计划分发它,最好在发布说明/手册中列出所有的假设。如果你这样做,你可以将寻找这些东西的关注点放在特定于发行版的安装脚本中。 - nsfyn55
正如我在问题中所说,我正在使用该功能作为项目完全可选的一部分。我不希望人们因为安装了这个“依赖项”而需要重新编译我的项目。 - Cobra_Fast
他们不需要编译(除非他们想要)。你仍然可以分发预编译的二进制文件。我只是说大多数应用程序处理这个问题的方式是在安装时按照每个发行版检查依赖项。这样,您可以使用支持的发行版上可用的任何工具来检查依赖项。如果您的项目的这一部分是可选的并且单独安装,则在安装它时运行适当的检查。 - nsfyn55
可能是这个问题的重复 如何从Bash脚本中检查程序是否存在 - Gerard Roche
5个回答

3

关于如何在您的代码中发现命令是否存在的问题,您可以尝试检查返回值。

int ret = system("ls --version > /dev/null 2>&1"); //The redirect to /dev/null ensures that your program does not produce the output of these commands.
if (ret == 0) {
    //The executable was found.
}

你也可以使用popen来读取输出。结合其他答案中建议的whereis和type命令。
char result[255];
FILE* fp = popen("whereis command", "r");
fgets(result, 255, fp);
//parse result to see the path of the bin if it has been found.
pclose(check);

或者使用类型:

FILE* fp = popen("type command" , "r"); 
< p > type 命令的结果比较难解析,因为其输出取决于你要查找的内容(二进制、别名、函数、未找到)。


"whereis"有时候被简写为"where",但是直接使用"which"可能会更好。 - srcspider

0

使用 which 命令,你可以检查 system() 返回的值(如果找到则为0),或者命令的输出(无输出表示未找到):

$ which which
/usr/bin/which
$ echo $?
0
$ which does_t_exist
$ echo $?
1

1
which 不是一个标准命令,无法告诉你关于 shell 内置命令等信息。 - tripleee

0

您可以在Linux(或任何POSIX操作系统)上使用stat(2)来检查文件是否存在。


1
使用stat查找文件可能很困难,因为它可能安装在非标准位置。 - arunkumar
这并不太困难,因为system()使用$PATH。在$PATH中搜索所有路径很简单直接。 - chmeee
一个简单的循环和字符串连接就可以完成任务。伪代码-C: for (int i = 0; i < num_paths; i++) { struct stat sb; char *path; asprintf(&path, "%s/foo", paths[i]); if (stat(path, &sb) == 0) break; } - chmeee

0

如果你运行一个shell,从"type commandname"的输出可以告诉你commandname是否可用,如果可用,它是如何提供的(别名,函数,二进制路径)。你可以在这里阅读type的文档:http://ss64.com/bash/type.html


0

我会遍历当前的 PATH,看看是否可以在其中找到它。这就是我最近使用程序的可选部分所需的 agrep 安装的方法。或者,如果您不信任 PATH,但有自己要检查的路径列表,请使用该列表。

我怀疑这不是您需要检查是否为内置的 shell 命令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接