我正在Linux上用C开发控制台应用程序。
现在,它的可选部分(不是必需的)取决于可用的命令/二进制文件。
如果我用system()进行检查,则会得到sh: command not found作为不需要的输出,并且它会将其检测为存在。 那么,如何检查命令是否存在?
由于我正在使用C而不是BASH,因此与检查Bash脚本中是否存在程序不是重复的。
您传递给system()的是什么?
我使用版本选项(例如system("ls --version"))传递程序名称。好吧,至少那是我的主意。
在安装时检查所有相关命令/软件包版本是否更有意义?如果在编译/安装应用程序时它们在那里,那么您可以合理地假设它们在运行时就在那里。如果您打算分发它,则最好在发行说明/手册页中列出所有假设。如果这样做,您可以只考虑在发行版特定的安装脚本中搜索这些内容。
就像我在问题中说的那样,我在项目的完全可选部分中使用了该功能。我不希望人们仅仅因为他们安装了这种依赖关系而需要重新编译我的项目。
好吧,他们不需要编译(除非他们愿意)。您仍然可以分发预编译的二进制文件。我只是说大多数应用程序通过在安装时按发行版检查依赖项来处理此问题的方式。这样,您可以使用受支持的发行版上可用的任何工具来检查依赖性。如果项目的此部分是可选的并单独安装,则在安装时将运行相应的检查。
Bash脚本中检查程序是否存在的可能重复项
回答有关如何发现命令与代码一起存在的问题。您可以尝试检查返回值。
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");
type命令的结果很难解析,因为它的输出取决于您要查找的内容(二进制,别名,函数,未找到)而有所不同。
whereis有时是where,最好只使用which
我只需要浏览当前的PATH,看看是否可以在其中找到它。这就是我最近对需要安装agrep的程序的可选部分所做的工作。或者,如果您不信任PATH,但拥有自己的路径列表来进行检查,请使用该列表。
我怀疑您是否需要检查外壳是否是内置的。
如果运行外壳程序," type commandname"类型的输出将告诉您commandname是否可用,如果可用,则如何提供(别名,函数,二进制路径)。您可以在此处阅读type的文档:http://ss64.com/bash/type.html
使用which,您可以检查system()返回的值(如果找到,则返回0)或命令的输出(找不到未找到的输出):
$ which which
/usr/bin/which
$ echo $?
0
$ which does_t_exist
$ echo $?
1
which不是标准命令,并且无法告诉您有关shell内置等的信息。
您可以在Linux(或任何POSIX OS)上使用stat(2)来检查文件的存在。
使用stat搜索文件会很困难,因为它可以安装在非标准位置。
这不太困难,因为system()使用$ PATH。 直接搜索$ PATH中的所有路径。
但是stat不使用$ PATH。
一个简单的循环和字符串连接就可以完成任务。 伪C:for(int i = 0; i