为何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函数的返回值是终止状态+信号编号的值.