return code of system()

2020-03-01 18:04发布

问题:

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

回答1:

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;
}


回答2:

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.



回答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:

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



回答5:

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.



回答6:

Try grep "[s]uduko"

as full: ps aux | grep [s]uduko

This will not show grep itself.



回答7:

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


标签: c unix system ps