Calling system () does not give the expected result in C

I wrote this code to check if any process called Rahul running:

  int ret = -1; char cmd[40]="pgrep -f Rahul > /dev/null"; ret = WEXITSTATUS(system(cmd)); printf("%d\n", ret); 

This code prints 0 , indicating that the process whose name contains Rahul exists, although I checked that such a process did not execute.

I changed the code and removed the output redirection part, so the modified code:

  int ret = -1; char cmd[40]="pgrep -f Rahul"; ret = WEXITSTATUS(system(cmd)); printf("%d\n", ret); 

Here, pin 1 , that is, the code is working fine.

Can someone tell me why this behavior?

+4
source share
1 answer

You have encountered a special behavior of bash when combined with pgrep.

First, we can simplify the task with simple commands:

 $ bash -c "pgrep -l -f Rahul"; echo $? 1 $ bash -c "pgrep -l -f Rahul > /dev/null"; echo $? 0 

Now we can see the insides of each of them:

 $ strace -tt -F bash -c "pgrep -l -f Rahul" 2>&1 | egrep "exec|clone|dup|write" 19:47:50.336043 execve("/bin/bash", ["bash", "-c", "pgrep -l -f Rahul"], [/* 55 vars */]) = 0 19:47:50.343015 execve("/usr/bin/pgrep", ["pgrep", "-l", "-f", "Rahul"], [/* 54 vars */]) = 0 19:47:50.353342 read(4, "Name:\twriteback\nState:\tS (sleepi"..., 1024) = 538 19:47:50.387157 read(4, "egrep\0exec|clone|dup|write\0", 2047) = 27 19:47:50.387668 write(1, "3031 strace\n", 123031 strace 

compared with:

 $ strace -tt -F bash -c "pgrep -l -f Rahul > /dev/null" 2>&1 | egrep "exec|clone|dup|write" 19:48:44.669747 execve("/bin/bash", ["bash", "-c", "pgrep -l -f Rahul > /dev/null"], [/* 55 vars */]) = 0 19:48:44.676633 clone(Process 3046 attached [pid 3046] 19:48:44.677336 dup2(3, 1) = 1 [pid 3046] 19:48:44.677435 execve("/usr/bin/pgrep", ["pgrep", "-l", "-f", "Rahul"], [/* 54 vars */]) = 0 [pid 3046] 19:48:44.687636 read(4, "Name:\twriteback\nState:\tS (sleepi"..., 1024) = 538 [pid 3046] 19:48:44.727507 read(4, "egrep\0exec|clone|dup|write\0", 2047) = 27 [pid 3046] 19:48:44.728375 write(1, "3039 strace\n3045 bash\n", 22) = 22 

see that only in the second is the "clone" executed. pgrep then finds the shell as a matching process.

+3
source

All Articles