【博客129】执行系统调用函数system介绍

内容: 当我们写代码的时候需要在进程代码中去执行一个shell脚本,可以使用system()函数

函数原型:

 int system(const char * string); 

函数说明:

system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的
命令,此命>令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT
和SIGQUIT 信号则会被忽略。 

函数实现:

int system(const char * cmdstring)
{
    pid_t pid;
    int status;

if(cmdstring == NULL)
{
    return (1); //如果cmdstring为空,返回非零值,一般为1
}

if((pid = fork())<0)
{
    status = -1; //fork失败,返回-1
}
else if(pid == 0)
{
    execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
    _exit(127); // exec执行失败返回127,注意exec只在失败时才返回现在的进程,成功的话现在的进程就不存在啦~~
}
else //父进程
{
    while(waitpid(pid, &status, 0) < 0)
    {
        if(errno != EINTR)
        {
            status = -1; //如果waitpid被信号中断,则返回-1
            break;
        }
    }
}

    return status; //如果waitpid成功,则返回子进程的返回状态
}

执行步骤:

1.fork一个子进程;
2.在子进程中调用exec函数去执行command;
3.在父进程中调用wait去等待子进程结束。

失败分析:
1.对于fork失败,system()函数返回-12.如果exec执行成功,也即command顺利执行完毕,则返回command通过exit或return返回的值。
(注意,command顺利执行不代表执行成功,比如command:"rm text.txt",不管文件存不存在
该command都顺利执行了)

3.如果exec执行失败,即command没有顺利执行,比如被信号中断,或command命令根本不存在,system()函数返回127.
如果command为NULL,则system()函数返回非0值,一般为1.

最重要的是使用system()最重要的就是如何进行返回值判断:

分三个部分判断:
1.阶段1:创建子进程等准备工作。如果失败,返回-12.调用/bin/sh拉起shell脚本,如果拉起失败或者shell未正常执行结束,原因值被写入到status中

注意:
只要能够调用到/bin/sh,并且执行shell过程中没有被其他信号异常中断,都算正常结束。不管shell脚本中
返回什么原因值,是0还是非0,都算正常执行结束。即使shell脚本不存在或没有执行权限,也算正常执行束。

那么如何判断shell脚本是否正常执行结束呢?系统提供了宏:
WIFEXITED(status)。如果WIFEXITED(status)为真,则说明正常结束。

3.如果shell脚本正常执行结束,将shell返回值填到status中

我们可以使用系统提供的宏:WEXITSTATUS(status)
(注意:在shell脚本中会通过返回值判断本脚本是否正常执行,如果成功返回0,失败返回正数。)

综上我们判断system是否执行失败是如下:
ret = system(“XXX”);
ret == -1 || !WIFEXITED(ret) || 0 != WEXITSTATUS(ret)

大四学生一枚,文章均非抄袭或者模仿,均为原创,仅代表个人观点,如果文章有错误的地方,欢迎在下方提出,每条评论我都会去认真看并回复,同时感谢指正的前辈

发布了158 篇原创文章 · 获赞 34 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43684922/article/details/103395221