10
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main() {

int res = system("ps ax -o pid -o command | grep sudoku | grep gnome > /dev/null");

printf("res = %d \n", res);

return 0;
}

I want to see if sudoku is running or not by just examining the return code of system() (or any other call for that matter). I do not want any output to be printed anywhere.

I do not quite understand the return code of system() even after looking at the man page

Whether sudoku is running or not, I get res = 0.

nmichaels
  • 45,418
  • 12
  • 95
  • 127
hari
  • 8,775
  • 24
  • 67
  • 104

7 Answers7

9

First of all, you should be using WEXITSTATUS(res). The standard clearly states:

If command is not a null pointer, system() shall return the termination status of the command language interpreter in the format specified by waitpid().

I suspect the problem is that the command actually succeeds (grep finds itself). Try not to redirect the output for a moment:

[cnicutar@fresh ~]$ ./test
  989 sh -c ps ax -o pid -o command | grep sudoku | grep gnome
res = 0

So, since every commands executes successfully, the return code will be 0 :-). You might have better luck with pgrep and the like.

cnicutar
  • 164,886
  • 23
  • 329
  • 361
  • 1
    Thanks cnicutar, but I am not getting you here. `grep` on `ps` is not successful. I also tried not redirecting the o/p, in that case, I can see the command on the STDOUT bur res is still 0. – hari Aug 01 '11 at 21:33
  • 1
    @hari You can see it because it actually succeeds (as I explained). Try `pgrep sudoku` instead. – cnicutar Aug 01 '11 at 21:34
7

The way you are trying to capture the output of grep may not work.

Based on the post: C: Run a System Command and Get Output?

You can try the following. This program uses popen()

#include <stdio.h>
#include <stdlib.h>


int main( int argc, char *argv[] )
{

    FILE *fp;
    int status;
    char path[1035];

    /* Open the command for reading. */
    fp = popen("/bin/ps -x | /usr/bin/grep gnome-sudoku", "r"); 
    if (fp == NULL) {
        printf("Failed to run command\n" );
        exit;
    }
    /* Read the output a line at a time - output it. */
    while (fgets(path, sizeof(path)-1, fp) != NULL) {
      printf("%s", path);
    }
    pclose(fp);
return 0;
}

For reference to popen() see:

http://linux.die.net/man/3/popen

And if you try to use grep then you can probably redirect the output of grep and read the file in the following way:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main() {

    int res = system("ps -x | grep SCREEN > file.txt");
    char path[1024];
    FILE* fp = fopen("file.txt","r");
    if (fp == NULL) {
      printf("Failed to run command\n" );
      exit;
    }
    // Read the output a line at a time - output it.
    while (fgets(path, sizeof(path)-1, fp) != NULL) {
      printf("%s", path);
    }
    fclose(fp);
    //delete the file
    remove ("file.txt");
    return 0;
}
Community
  • 1
  • 1
A. K.
  • 26,873
  • 15
  • 44
  • 74
3

If you have pgrep, use it instead of your shell pipeline.

system("pgrep -x gnome-sudoku >/dev/null");

When you call

system("ps ax -o pid -o command | grep sudoku | grep gnome > /dev/null");

the system executes

sh -c 'ps ax -o pid -o command | grep sudoku | grep gnome > /dev/null'

which shows up in ps and passes the grep filters.

ephemient
  • 180,829
  • 34
  • 259
  • 378
  • 1
    I am on `ubuntu` and it seems, pgrep is not working: $ ps ax -o pid -o command | grep gnome-sudoku 2638 python /usr/games/gnome-sudoku 2657 grep --color=auto gnome-sudoku $ pgrep -x gnome-sudoku $ – hari Aug 01 '11 at 21:43
  • 1
    @hari: On Linux, "pgrep" only sees the first 15 characters of the process name (i.e., the "Name" field of /proc/PID/status). I think you want to add a "grep -v ps" to your pipeline... – Nemo Aug 01 '11 at 21:48
  • @Nemo: Thanks, are you suggesting to add "grep -v ps" to "pgrep" ?? – hari Aug 01 '11 at 21:53
  • @hari: No, I am suggesting ditching `pgrep`, go with your original solution, add add `grep -v ps` (or maybe `grep -v grep`) to the pipeline. – Nemo Aug 02 '11 at 00:12
1

Try grep "[s]uduko"

as full: ps aux | grep [s]uduko

This will not show grep itself.

Neels
  • 2,489
  • 6
  • 31
  • 39
serg
  • 11
  • 1
1

A workaround is to redirect the output to a file e.g.:

> /tmp/isRunningSudoku

then open the file /tmp/isRunningSudoku and store it to your res variable

Eric Fortis
  • 13,518
  • 6
  • 37
  • 57
1

ps and grep returned succesfully; they fork'd, exec'd, and they did not return any error status. That says absolutely nothing about whether or not sudoku is running.

Overall your code is hacky. However, if you want to continue to hardcode these commands you can use popen and observe what the commands actually printed, rather than looking at whether or not system succeeded.

asveikau
  • 35,672
  • 2
  • 48
  • 66
0

In short, your command will always succeed because it is likely to be reserved in the process space before all the data is interperted.

That means your ps lists itself, and then the greps succeed because

grep suduko

will match

ps | grep suduko
Edwin Buck
  • 64,804
  • 7
  • 90
  • 127