开发者

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

开发者 https://www.devze.com 2023-03-28 07:12 出处:网络
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.

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. 开发者_C百科gifsicle) is available on the system executing the C++ code?


You could invoke which first.

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.

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.


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.


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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号