system函数返回值探究

http://blog.chinaunix.net/uid-24774106-id-3048281.html?page=3

遇到system调用脚本,结果返回了256的情况,那么如何判断脚本是否正常成功调用,即取到脚本的真正返回值

system是个综合的操作,分解开来看就是相当于执行了

1 fork  生成一个子进程。

2 在子进程执行 execl("/bin/sh","sh","-c" command,(char*)0);

3 waitpid

 

下面进入正题,返回值:

1 如果fork失败了,或者waitpid返回除了EINTR之外的错误,system返回 -1;

2 execl执行失败,其返回值如同shell执行了"exit(127)" 一样。(非法命令)

3 如果上述三步都执行成功,那么,system返回值是shell的终止状态。

 

如果/bin/sh拉起shell命令失败,或者是shell命令没有正常执行 (比如命令根本就是非法的命令),那么,将原因填入status的8~15位。

这样就比较容易根据system的返回值进行问题定位了:

-1:创建子进程失败
对于其它值,先用返回值除以256,商对应的含义如下:
0:命令运行成功
1:通用未知错误
2:误用shell命令
126:命令不可执行
127:没有找到命令
128:无效退出参数
130:命令通过Ctrl+C终止
255:退出状态码越界

libin@libin:~/program/C/Linux/system$ ./tsys "nosuchcmd"

sh: nosuchcmd: not found

status = 32512

normal termination,exit status = 127

我们看到了,nosuchcmd不是shell支持的命令,所以,shell命令返回了127,对于system函数,返回值为 127*256 = 32512;因为shell的返回值是 system返回值的8~15位。

如果shell顺利执行完毕,那么将shell的返回值填到system返回值的8~15位。

 这里需要强调以下,所谓顺利执行完毕,并不是说,命令command执行成功,而是指  /bin/sh顺利调用,执行期间没有被信号异常终止,这都算是顺利执行完毕。

libin@libin:~/program/C/Linux/system$ ./tsys "ls /noexisted"
ls: 无法访问/noexisted: 没有那个文件或目录
status = 512
normal termination,exit status = 2

libin@libin:~/program/C/Linux/system$ ls /noexist
ls: 无法访问/noexist: 没有那个文件或目录
libin@libin:~/program/C/Linux/system$ echo $?
2
libin@libin:~/program/C/Linux/system$

我们看到了,虽然/noexist文件并不存在,ls这条命令执行出了错,但是仍然属于shell顺利执行完毕。 ls /noexist的错误吗是2,所以,system函数的返回值为 2*256 = 512.

所以,对于system函数,返回值是由两部分组成的,低8位值表示所执行的脚本在执行过程中所接收到的信号值,其余的位表示的脚本exit退出时所设置的值,

即脚本内exit退出是的值的低8位,在system返回值的低9-16位


各位可能比较感兴趣的是,如果我知道system的返回值,如何知道我的命令的返回值呢?手册中有这么一句话:

  1. Thus, the exit code of the command will be WEXITSTATUS(status)

    看到了WEXITSTATUS(status),就是command的返回值。当然前提条件是shell命令顺利执行完毕。即:

  1. WIFEXITED(status) ! =0
 
下面是原文作者的测试代码:
#define _XOPEN_SOURCE

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

#include<signal.h>
#include<sys/wait.h>

void pr_exit(int status)
{
        printf("status = %d\n",status);
    if(WIFEXITED(status))
        {
         printf("normal termination,exit status = %d\n",WEXITSTATUS(status));
        }

        else if(WIFSIGNALED(status))
        {
         printf("abnormal termination,signal number =%d%s\n",
                                WTERMSIG(status),
#ifdef WCOREDUMP
                                WCOREDUMP(status)?"core file generated" : "");
#else
                "");
#endif
        }
}


int main(int argc,char* argv[])
{
        int status;

        if(argc<2)
        {
         fprintf(stderr,"usage:tsys cmd\n");
                 return -1;
        }

        if((status = system(argv[1]) )<0)
        {
         fprintf(stderr,"system error\n");
                return -2;
        }

        pr_exit(status);
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值