C 使用System Call:exec 执行Python 脚本(或其他程序)

以前写java的时候有过几次想调用Python的念头,但是当时水平比较低不知道怎么办(但是好像才学编程一学期吧,什么都不懂,唉,其实有好多库可以调用)。

最近在上操作系统课的时候讲到System Call。其中有一个exec正好可以完成上述工作,只不过是从C里执行而已。

System Call 就是操作系统与应用程序之间的接口。当在user space 中调用system call时会进入kernel mode。(具体就不说了,网上好多)

exec是一个比较复杂的system call,它会将当前进程的 core image( 也就是当前进程地址空间中的内容) 替换掉。举个例子吧,当调用fork的时候,子进程里的内容和父进程里的内容一模一样,只不过子进程和父进程的pid不同,但是如果在子进程中调用exec system call, 此时子进程里的东西就全被替换为新的东西,在下面的例子中,子进程中的内容和我们直接在终端中使用命令 “python /Users/alex/Desktop/test.py”产生的进程里的东西一模一样。

在下面的例子中,我们调用的是execve,我觉得大家应该还见过execvp, execl, execle等等一席勒以exec开头的函数,但实际上它们只是接受的参数不同而已,本质上最后调用的还是exec,这里有个回答解释了这些的区别 链接

说一下execve的参数说明,详情可以参阅这里

#include <unistd.h>
int execve(const char *filename, char *const argv[],
                  char *const envp[]);

其中

  • filename
    filename must be either a binary executable, or a script starting with a line of the form:
    #! interpreter [optional-arg]
    filename必须是一个二进制可执行文件,或者是一个有着以上形式的脚本

  • argv
    argv is an array of argument strings passed to the new program. By
    convention, the first of these strings (i.e., argv[0]) should contain
    the filename associated with the file being executed.
    argv是一个参数数组,第一个参数一般都是之前那个filename

  • envp
    envp is an array of strings, conventionally of the form key=value, which are passed as environment to the new program. The argv and envp arrays must each include a null pointer at the end of the array.
    最后一句很重要,这两个数组最后都要有一个空指针。

例子如下:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
    int status = 100;
    int execres = 100;
    //参数,/usr/bin/python前的“/“不要漏
    char *argvlist[]={"/usr/bin/python", "/Users/alex/Desktop/test.py", NULL};
    printf("start\n");
    if (fork()!=0){
        waitpid(-1,&status,0);
        printf("parent process finished, status is %d\n", status);
    }else{
        printf("child process\n");
        execres = execve(argvlist[0],argvlist,NULL);
        //如果调用execve成功的话,以下打印的东西是不可见的,因为exec会将原来进程中的内容全部替换掉
        printf("child process runing, res is %d\n",execres);
    }
}
执行结果如下:
![这里写图片描述](https://img-blog.csdn.net/20170207205929513?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQWxleFpoYW5nNjc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

最后还有一个小问题,一开始我是在sublime中build然后运行的,但是,结果出错了,这应该是sublime输出流又问题,sublime下的输出一直就不怎么好用。。

猜你喜欢

转载自blog.csdn.net/AlexZhang67/article/details/54894918