2015-08-17 57 views
4

我名字由Rahul任何進程正在運行或不寫了這個代碼來檢查:調用系統()不給預期輸出用C

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

此代碼打印0表明一個過程,其名字包含Rahul存在雖然我已驗證沒有這樣的過程正在運行。

我修改了代碼,並刪除重定向輸出部分,因此修改後的代碼是:

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

這裏,輸出爲1,也就是說,代碼工作正常。

有人可以建議爲什麼這種行爲?

+1

或者,您可以嘗試使用'pgrep -c'使'pgrep'不產生輸出。 – fuz

+1

@FUZxxl:我認爲「pgrep -c」會產生一些匹配的進程。 –

+0

@pasabaporaqui啊,是的,這是正確的。我以爲'pgrep' *返回*這個數字,而不是打印出於某種原因。不幸的是,'pgrep'沒有'grep'這樣的'-q'選項。 – fuz

回答

3

您正面臨着「bash」與「pgrep」相結合的特殊行爲。

首先,我們可以通過簡單的命令簡化問題:

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

現在,我們可以看到每一個的內部:

$ 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 

則爲:

$ 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 

看到只有第二個「克隆」完成。然後「pgrep」將找到shell作爲匹配過程。