内容: 当我们写代码的时候需要在进程代码中去执行一个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()函数返回-1。
2.如果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:创建子进程等准备工作。如果失败,返回-1。
2.调用/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)
大四学生一枚,文章均非抄袭或者模仿,均为原创,仅代表个人观点,如果文章有错误的地方,欢迎在下方提出,每条评论我都会去认真看并回复,同时感谢指正的前辈