简体   繁体   English

通过C++判断Linux中是否安装了程序

[英]Determine via C++ whether a program is installed in Linux

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.我想从我的 C++ 代码中对 Linux 程序进行system调用,但我想先检查该程序是否安装在用户的机器上。

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.在 Ubuntu 中,我可以确定是否使用dpkg -s gifsicle之类的系统调用安装了与该程序关联的 package 并解析其 Z78E6221F6393D1356681CEDB398F1。 gifsicle here is the program name.这里的gifsicle是程序名称。

However, it's possible that the program (eg gifsicle ) was compiled from source and thus does not appear in the Ubuntu package repository.但是,该程序(例如gifsicle )可能是从源代码编译的,因此不会出现在 Ubuntu package 存储库中。

What's a good programmatic way of determining whether a program (eg gifsicle ) is available on the system executing the C++ code?确定程序(例如gifsicle )在执行 C++ 代码的系统上是否可用的一种好的编程方式是什么?

You could invoke which first.你可以先调用which

The exit status indicates whether it could find the specified executable on the path.退出状态指示它是否可以在路径上找到指定的可执行文件。

There is no standard package manager for Linux, so dpkg is definitely the wrong answer. Linux 没有标准的 package 管理器,所以dpkg绝对是错误的答案。

For security and correctness reasons, it is probably unwise to rely on the user's PATH to locate an executable.出于安全和正确性的原因,依靠用户的 PATH 来定位可执行文件可能是不明智的。 So you probably should already be using the fully-qualified path (eg /usr/bin/gifsicle ) in your call to system .因此,您可能应该已经在调用system时使用了完全限定的路径(例如/usr/bin/gifsicle )。

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) (如果您将/usr/bin/gifsicle放入变量中,则可以加分)

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.更难 - 但可以说“更正确” - 答案是避免system并自己执行fork + execl ,检查execl以查看它是否导致ENOENT或类似的结果。 Communicating the failure back to the parent process could be annoying, though.但是,将故障传达回父进程可能会很烦人。

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() ).如果您确定程序在用户的 PATH 中,您可以调用which命令(也使用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.例如,可以将Doxygen配置为调用dot来生成图表。 By default, it tries to invoke dot as it it were on the PATH environment variable.默认情况下,它会尝试在 PATH 环境变量中调用dot 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.如果找不到,它会警告用户它找不到dot程序并且没有设置DOT_PATH配置值。 This solution has the advantage of being simple and working on other systems too.该解决方案的优点是简单并且也适用于其他系统。

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. package 管理器接近,但并非一切都通过 package 管理器。

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?如果调用失败,并且system指示找不到可执行文件,那么就假设它没有安装和/或不可用——这有关系吗? — and move on to some fallback alternative. - 并继续使用一些后备替代方案。

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 http://www.linuxselfhelp.com/gnu/autoconf/html_chapter/autoconf_3.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM