11
#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.

7
  • 1
    Did you try to run your code for some other programs, e.g. firefox or vi editor (when they are running) Commented Aug 1, 2011 at 21:25
  • Yes, I did try different processes. Commented Aug 1, 2011 at 21:28
  • 8
    Handy trick: grep -e "[s]udoku" Commented Aug 1, 2011 at 21:31
  • and why is grep gnome in there? That seems to complicate the test uncessarily. To remove all output, you need to add .. > /dev/null 2>&1. Good luck. Commented Aug 1, 2011 at 21:35
  • If you want to write a shell script, why not just write a shell script? C is a horrible tool for the job. Commented Aug 1, 2011 at 21:56

7 Answers 7

11

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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 You can see it because it actually succeeds (as I explained). Try pgrep sudoku instead.
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; } 

1 Comment

Thanks, it seems that your solution with popen is the one I will have to use.
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.

4 Comments

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: 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: Thanks, are you suggesting to add "grep -v ps" to "pgrep" ??
@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.
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

Comments

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.

Comments

1

Try grep "[s]uduko"

as full: ps aux | grep [s]uduko

This will not show grep itself.

Comments

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 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.