3

I am developing a console application in C on linux.

Now an optional part of it (its not a requirement) is dependant on a command/binary being available.

If I check with system() I'm getting sh: command not found as unwanted output and it detects it as existent. So how would I check if the command is there?


Not a duplicate of Check if a program exists from a Bash script since I'm working with C, not BASH.

Cobra_Fast
  • 15,671
  • 8
  • 57
  • 102
  • What are you passing to `system()`? – arunkumar Aug 28 '11 at 17:45
  • Im passing the program name with the version option, like `system("ls --version")`. Well, at least that was my idea. – Cobra_Fast Aug 28 '11 at 17:55
  • 1
    Wouldn't it make more sense to check for all dependent commands/ package versions at install time? If they are there when the application is compiled/installed you can probably make a reasonable assumption they are there at run time. If its something you plan on distributing it would probably just be a good idea to list all your assumptions in the release notes/ man page. If you did this you could just house the concern of searching for these things in distro specific install scripts. – nsfyn55 Aug 28 '11 at 18:22
  • As I said in my question, I'm using the feature for a totally optional part of my project. I dont want people to need to recompile my project just because they installed this 'dependancy'. – Cobra_Fast Aug 28 '11 at 20:21
  • Well they wouldn't need to compile(unless they wanted to). You could still distribute pre-compiled binaries. I'm just saying that the way most applications deal with this by checking for dependencies on a per distro basis at install time. That way you can use whatever tools are available on your supported distributions to check for dependencies. If this part of your project is optional and installed separately then you'd run the appropriate checks when you installed it. – nsfyn55 Aug 29 '11 at 12:01
  • Possible duplicate of [Check if a program exists from a Bash script](http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script) – Gerard Roche Oct 16 '16 at 05:04

5 Answers5

3

To answer your question about how to discover if the command exists with your code. You can try checking the return value.

int ret = system("ls --version > /dev/null 2>&1"); //The redirect to /dev/null ensures that your program does not produce the output of these commands.
if (ret == 0) {
    //The executable was found.
}

You could also use popen, to read the output. Combining that with the whereis and type commands suggested in other answers -

char result[255];
FILE* fp = popen("whereis command", "r");
fgets(result, 255, fp);
//parse result to see the path of the bin if it has been found.
pclose(check);

Or using type:

FILE* fp = popen("type command" , "r"); 

The result of the type command is a bit harder to parse since it's output varies depending on what you are looking for (binary, alias, function, not found).

arunkumar
  • 32,803
  • 4
  • 32
  • 47
0

You can use stat(2) on Linux(or any POSIX OS) to check for a file's existence.

chmeee
  • 3,608
  • 1
  • 21
  • 28
  • 1
    It would be hard to search for a file using stat, since it could be installed in non-standard locations. – arunkumar Aug 28 '11 at 17:47
  • It's not too difficult, since system() uses $PATH. Searching through all paths in $PATH is straight forward. – chmeee Aug 28 '11 at 18:03
  • A simple loop and string concatenation can do the job. pseudo-C: for (int i = 0; i < num_paths; i++) { struct stat sb; char *path; asprintf(&path, "%s/foo", paths[i]); if (stat(path, &sb) == 0) break; } – chmeee Aug 28 '11 at 18:24
0

Use which, you can either check the value returned by system() (0 if found) or the output of the command (no output equal not found):

$ which which
/usr/bin/which
$ echo $?
0
$ which does_t_exist
$ echo $?
1
Daniel Da Cunha
  • 1,004
  • 11
  • 15
0

If you run a shell, the output from "type commandname" will tell you whether commandname is available, and if so, how it is provided (alias, function, path to binary). You can read the documentation for type here: http://ss64.com/bash/type.html

tripleee
  • 175,061
  • 34
  • 275
  • 318
0

I would just go through the current PATH and see whether you can find it there. That’s what I did recently with an optional part of a program that needed agrep installed. Alternately, if you don’t trust the PATH but have your own list of paths to check instead, use that.

I doubt it’s something that you need to check with the shell for whether it’s a builtin.

tchrist
  • 78,834
  • 30
  • 123
  • 180