通过 C++ 确定Linux 中是否安装了程序
我想从我的 C++ 代码对 Linux 程序进行系统
调用,但我想首先检查该程序是否安装在用户的计算机上。
在 Ubuntu 中,我可以使用 dpkg -s gifsicle 等系统调用来确定是否安装了与该程序关联的软件包,并解析其输出。 gifsicle
这里是程序名称。
但是,该程序(例如 gifsicle
)可能是从源代码编译的,因此不会出现在 Ubuntu 软件包存储库中。
有什么好的编程方法可以确定程序(例如 gifsicle
)在执行 C++ 代码的系统上是否可用?
I would like to make a system
call to a Linux program from my C++ code, but I would like to check whether the program is installed on the user's machine first.
In Ubuntu, I can determine whether a package associated with that program was installed using a system call like dpkg -s gifsicle
and parse its output. gifsicle
here is the program name.
However, it's possible that the program (e.g. gifsicle
) was compiled from source and thus does not appear in the Ubuntu package repository.
What's a good programmatic way of determining whether a program (e.g. gifsicle
) is available on the system executing the C++ code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以首先调用
which
。退出状态指示是否可以在路径上找到指定的可执行文件。
You could invoke
which
first.The exit status indicates whether it could find the specified executable on the path.
Linux 没有标准的包管理器,因此 dpkg 绝对是错误的答案。
出于安全性和正确性的原因,依赖用户的 PATH 来查找可执行文件可能是不明智的。因此,您可能应该已经在调用
system
时使用完全限定路径(例如/usr/bin/gifsicle
)。如果是这样,您的问题的简单答案是:(
如果您将
/usr/bin/gifsicle
放入变量中,则会获得加分)更难的 - 但可以说“更正确” - 答案是避免
system
并自己执行fork
+execl
,检查execl
看看它是否会产生ENOENT< /code> 或类似的。不过,将失败信息传达给父进程可能会很烦人。
There is no standard package manager for Linux, so
dpkg
is definitely the wrong answer.For security and correctness reasons, it is probably unwise to rely on the user's PATH to locate an executable. So you probably should already be using the fully-qualified path (e.g.
/usr/bin/gifsicle
) in your call tosystem
.If so, the easy answer to your question is:
(Bonus points if you put
/usr/bin/gifsicle
into a variable)The harder -- but arguably "more correct" -- answer is to avoid
system
and dofork
+execl
yourself, checking theexecl
to see if it results inENOENT
or similar. Communicating the failure back to the parent process could be annoying, though.基本上,为了涵盖手动安装程序且未在已安装软件包数据库中注册的情况,您必须扫描整个文件系统以确保未安装该程序。
如果您确定该程序位于用户的 PATH 中,则可以调用
which
命令(也使用system()
)。然而,常见的解决方案是允许用户通过配置选项覆盖可执行文件的路径。例如,Doxygen 可以配置为调用 dot 生成图表。默认情况下,它会尝试调用 PATH 环境变量中的
dot
。如果找不到,它会警告用户找不到dot
程序,并且DOT_PATH
配置值尚未设置。该解决方案的优点是简单,并且也可以在其他系统上运行。Basically, to cover the case where the program is installed manually and is not registered in the installed packages database, you would have to scan the entire file system to guarantee that the program is not installed.
If you are sure the program is in the user's PATH, you can invoke the
which
command (also usingsystem()
).However, the common solution to this is to allow the user to override the path to the executable via a configuration option. For example, Doxygen may be configured to invoke dot to generate diagrams. By default, it tries to invoke
dot
as it it were on the PATH environment variable. If it cannot be found, it warns the user that it cannot find thedot
program and that theDOT_PATH
configuration value has not been set. This solution has the advantage of being simple and working on other systems too.正如你所说,确定是否安装了某些东西并不简单。事实上,“安装”并没有明确的定义;包管理器很接近,但并不是所有事情都经过包管理器。
为什么不尝试调用可执行文件呢?如果调用失败,并且
system
指示未找到可执行文件,那么就假设它尚未安装和/或不可用 - 哪一个重要吗? ——然后转向一些后备替代方案。As you say, it's not trivial to determine whether something is installed. Really, there is no clear definition of "installed"; package managers get close, but not everything goes through a package manager.
Why not just attempt to invoke the executable? If the call fails, and
system
indicates that the executable was not found, then just presume that it's not installed and/or not available — does it matter which? — and move on to some fallback alternative.听起来您正在尝试制作配置脚本(或类似脚本),
请参阅 autoconf
http:// /www.linuxselfhelp.com/gnu/autoconf/html_chapter/autoconf_3.html
sounds like you are trying to make a configure script (or similar)
see autoconf
http://www.linuxselfhelp.com/gnu/autoconf/html_chapter/autoconf_3.html