我想从我的C ++代码中调用一个Linux程序的system
,但是我想先检查一下程序是否安装在用户的机器上。
在Ubuntu中,我可以确定是否使用dpkg -s gifsicle
等系统调用安装了与该程序关联的包并解析其输出。 gifsicle
这里是程序名称。
但是,程序(例如gifsicle
)可能是从源代码编译的,因此不会出现在Ubuntu软件包库中。
确定程序(例如gifsicle
)在执行C ++代码的系统上是否可用的良好编程方法是什么?
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
或类似。但是,将故障传递回父进程可能很烦人。
你可以先调用which
。
退出状态指示它是否可以在路径上找到指定的可执行文件。
正如你所说,确定是否安装了某些东西并非易事。真的,没有明确的“已安装”定义;包管理器接近,但并不是所有东西都通过包管理器。
为什么不尝试调用可执行文件?如果调用失败,并且system
指示找不到可执行文件,那么只是假设它没有安装和/或不可用 - 这有关系吗? - 并继续进行一些后备替代方案。
听起来你正在尝试制作配置脚本(或类似的)
看到autoconf
http://www.linuxselfhelp.com/gnu/autoconf/html_chapter/autoconf_3.html