首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

为何int ret=system("cmd") 不能返回正确的返回值。该怎么解决

2012-02-19 
为何int retsystem(cmd) 不能返回正确的返回值。 在linux下面,在一般的shell下,比如我运行一个命令。mach

为何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就是这个原因。

[解决办法]
《UNIX环境高级编程》这本书写的不错,看了这本书的system函数一节就明白了。
[解决办法]
int ret = system("ls /tmp");
printf("ret = %d\n", WEXITSTATUS(ret));
[解决办法]
popen函数是专门解决这类问题的。

对于以stdin和stdout为输入输出的程序,popen创建一个管道,fork一个子进程,关闭管道不使用的端,exec一个shell执行该命令,等待命令的终止。

FILE* popen(const char* cmdstring,const char* type);

如果是type等于"r",则通过返回的FILE*可以阅读cmdstring输出的数据;
如果type等于"w",则通过返回的FILE*可以向cmdstring写入数据

例子如下:

#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>

int main(int argc,char*argv[])
{
char szline[256];
FILE *fin;
if(argc!=2)
{
printf("usage: %s command\n",argv[0]);
return 0;
}
  
if((fin=popen(argv[1],"r"))==NULL)
{
printf("the command %s not exist\n",argv[1]);
return 0;
}
  
while(fgets(szline,sizeof(szline)-1,fin)!=NULL)
{
printf("frome command:%s",szline);
}
  
pclose(fin);
  
return 0;
}
[解决办法]
system函数的返回值是终止状态+信号编号的值.

热点排行