我想从我的C ++代码中调用Linux程序system
,但我想检查程序是否先安装在用户的机器上。
在Ubuntu中,我可以确定是否使用类似dpkg -s gifsicle
的系统调用安装了与该程序关联的包,并解析其输出。 gifsicle
这是程序名称。
但是,程序(例如gifsicle
)可能是从源代码编译的,因此不会出现在Ubuntu软件包库中。
确定程序(例如gifsicle
)在执行C ++代码的系统上是否可用的优秀编程方法是什么?
答案 0 :(得分:4)
您可以先调用which
。
退出状态表示它是否可以在路径上找到指定的可执行文件。
答案 1 :(得分:2)
Linux没有标准的软件包管理器,所以dpkg
肯定是错误的答案。
出于安全性和正确性的原因,依靠用户的PATH查找可执行文件可能是不明智的。因此,您可能应该在调用/usr/bin/gifsicle
时使用完全限定的路径(例如system
)。
如果是这样,您问题的简单答案是:
if (access("/usr/bin/gifsicle", X_OK) == 0) {
system("/usr/bin/gifsicle -my -args");
}
else if (errno == EACCESS) {
/* gifsicle not found */
}
else {
/* access() failed! Operating system is broken or Windows (or both) */
}
(如果将/usr/bin/gifsicle
放入变量,则为奖励积分)
更难 - 但可以说是“更正确” - 答案是避免system
并自己fork
+ execl
,检查execl
以查看是否结果为ENOENT
或类似。但是,将故障传回父进程可能很烦人。
答案 2 :(得分:1)
基本上,为了涵盖手动安装程序并且未在已安装的软件包数据库中注册的情况,您必须扫描整个文件系统以保证程序未安装。
如果您确定程序在用户的PATH中,则可以调用which
命令(也使用system()
)。
但是,常见的解决方案是允许用户通过配置选项覆盖可执行文件的路径。例如,Doxygen可以配置为调用dot来生成图表。默认情况下,它尝试调用dot
,因为它在PATH环境变量上。如果找不到,则会警告用户无法找到dot
程序,并且尚未设置DOT_PATH
配置值。该解决方案的优点是简单的和也适用于其他系统。
答案 3 :(得分:0)
正如您所说,确定是否安装了某些东西并非易事。真的,没有明确的“已安装”定义;包管理器接近,但并不是所有东西都通过包管理器。
为什么不尝试调用可执行文件?如果调用失败,并且system
表示找不到可执行文件,那么只是假定它没有安装和/或不可用 - 这有关系吗? - 并转向一些后备替代方案。
答案 4 :(得分:-2)
听起来你正在尝试制作配置脚本(或类似的)
参见autoconf
http://www.linuxselfhelp.com/gnu/autoconf/html_chapter/autoconf_3.html