问题
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