Determine via C++ whether a program is installed in Linux

[亡魂溺海] 提交于 2019-12-10 16:12:13

问题


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?


回答1:


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.




回答2:


You could invoke which first.

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




回答3:


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.




回答4:


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.




回答5:


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



来源:https://stackoverflow.com/questions/7045879/determine-via-c-whether-a-program-is-installed-in-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!