日期:2014-05-16  浏览次数:20698 次

为何int ret=system("cmd") 不能返回正确的返回值。

在linux     下面,     在一般的shell下,比如我运行一个命令。    
machine$     ls     /tm    
/bin/ls:     /tm:     No     such     file     or     directory    
machine$     echo     $?    
1    
machine$    
 
 
如果我把这个命令用system( "ls     /tm ");     为何我不能得到返回值1啊?    
 
 
iclx012$     more     dun.c    
#include     <unistd.h>    
#include     <iostream>    
 
using     namespace     std;    
int    
main(     int     argc,     char     **argv     )    
{    
          int     ret;    
 
          ret     =     system( "ls     /tm ");    
 
                              cout < < "ret= " < <ret < <endl;    
          exit(     ret     );    
}    
 
iclx012$     g++     dun.c    
iclx012$     ./a.out        
ls:     /tm:     No     such     file     or     directory    
ret=256    
iclx012$     echo     $?    
0    
iclx012$


有什么办法在我的程序里面得到我运行的命令的返回值啊?
分有的是。

------解决方案--------------------
system函数是由fork、execve和waitpid三个系统调用实现的。
所以如果execve出错,则直接调用_exit(256),所以变量ret的值等于256
在system函数执行时,会启动一个子进程运行shell,然后通过将ls /tm作为参数传给shell,如果shell命令运行有错,就调用exit XXX作为system的返回值返回,而XXX是system函数的返回值,而不是shell运行ls /tm后的返回值。
------解决方案--------------------
exit时,退出状态码只能是一个字节,超过部分被截取.
在父进程获取其状态时,把这个字节的数据放在了低地址第二个字节位置了.这些都是对补码操作的.

因此,exit (-1) 和exit (255)时,父进程获取的状态码是一样的,你无法区分.


因此,我们一般只根据退出状态为0或则非0来判断成功或失败,而不做进一步的区分.


------解决方案--------------------
测试代码:
#include <stdio.h>

int main()
{
char st;
int ret;

ret = system( "exit 0 ");
printf( "ret = %d\n ", ret/256);

ret = system( "exit 1 ");
printf( "ret = %d\n ", ret/256);

ret = system( "exit 2 ");
printf( "ret = %d\n ", ret/256);

ret = system( "exit 3 ");
printf( "ret = %d\n ", ret/256);

ret = system( "exit 4 ");
printf( "ret = %d\n ", ret/256);

return 0;
}

结果:
ret = 0
ret = 1
ret = 2
ret = 3
ret = 4

可见,ret/256应该就是你要的结果....不过不知道为什么要除以256,仅供参考....
------解决方案--------------------
因为system()返回的结果分两个部分,前面是命令的返回值,后面是运行因为信号终止时的信号值。所以要/256就是这个原因。