通过 C++ 确定Linux 中是否安装了程序

发布于 2024-11-29 06:02:09 字数 386 浏览 1 评论 0原文

我想从我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

内心荒芜 2024-12-06 06:02:09

您可以首先调用 which

退出状态指示是否可以在路径上找到指定的可执行文件。

You could invoke which first.

The exit status indicates whether it could find the specified executable on the path.

林空鹿饮溪 2024-12-06 06:02:09

Linux 没有标准的包管理器,因此 dpkg 绝对是错误的答案。

出于安全性和正确性的原因,依赖用户的 PATH 来查找可执行文件可能是不明智的。因此,您可能应该已经在调用 system 时使用完全限定路径(例如 /usr/bin/gifsicle)。

如果是这样,您的问题的简单答案是:(

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< /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 to system.

If so, the easy answer to your question is:

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) */
}

(Bonus points if you put /usr/bin/gifsicle into a variable)

The harder -- but arguably "more correct" -- answer is to avoid system and do fork + execl yourself, checking the execl to see if it results in ENOENT or similar. Communicating the failure back to the parent process could be annoying, though.

雪若未夕 2024-12-06 06:02:09

基本上,为了涵盖手动安装程序且未在已安装软件包数据库中注册的情况,您必须扫描整个文件系统以确保未安装该程序。

如果您确定该程序位于用户的 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 using system()).

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 the dot program and that the DOT_PATH configuration value has not been set. This solution has the advantage of being simple and working on other systems too.

烏雲後面有陽光 2024-12-06 06:02:09

正如你所说,确定是否安装了某些东西并不简单。事实上,“安装”并没有明确的定义;包管理器很接近,但并不是所有事情都经过包管理器。

为什么不尝试调用可执行文件呢?如果调用失败,并且 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.

策马西风 2024-12-06 06:02:09

听起来您正在尝试制作配置脚本(或类似脚本),

请参阅 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文