[学习笔记]达内纪录片day25 更新进程映像与编写自己的shell

    选择打赏方式

一、更新进程的映像
子进程通过复制父进程的资源创建的
子进程继承了父进程的PCB。 fd  image  环境变量
子进程和父进程的image完全相同。
在进程中改变进程的映像 
使用新的可执行文件布局进程的3G地址空间。

使用exec(3)家族的函数,可以更新进程的映像

fork会分配新的4G地址空间,vfork则不会分配新空间,父进程会被取代。


执行程序

#include <unistd.h>
int execve(const char *filename, char *const argv[],
                  char *const envp[]);
参数:
filename:指定了可执行程序的名字。必须是二进制可执行文件或者是脚本文件
argv:指向了传递给程序的参数列表   NULL代表列表的结束
envp:环境变量列表  传递给新进程的 NULL代表列表的结束
返回值:
成功   不返回  
失败  -1  errno被设置

家族函数
#include <unistd.h>
extern char **environ;  全局变量,指向了当前进程环境变量列表的首地址
int execl(const char *path, const char *arg, .../* (char  *) NULL */);
int execlp(const char *file, const char *arg, .../* (char  *) NULL */);
int execle(const char *path, const char *arg, .../*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);

exec   函数共有的
l   list(列表)
v   vector(向量表)
p  PATH  带p的,代表到PAHT环境变量指定的路径下找可执行程序。
如果不带p。必须指定可执行文件的路径
e   环境变量列表    不带e,继承父进程的环境变量列表
带e的,在执行新的进程的时候,传递一个自己指定的环境变量列表,覆盖掉从父进程继承的环境变量列表。


演示源码

exec:

#include <t_stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>

int main(void){
    char *p_argv[]={"ps","-o","pid,ppid,pgrp,comm",NULL};
    //创建子进程
    pid_t pid=fork();
    if(pid==-1)E_MSG("fork",-1);
    if(pid==0){//子进程执行的代码
        printf("child process...\n");
        //使用新的映像替换掉从父进程继承来的映像
        //execv("/bin/ps",p_argv);
        execlp("ps",p_argv[0],p_argv[1],p_argv[2],NULL);
        //加载新映像失败
        perror("execvp");
        exit(0);
    }else{//父进程执行的代码
        wait(NULL);//阻塞等待回收子进程的资源
        printf("parent process...\n");
    }
    return 0;
}

运行结果:

TIM截图20190805225252.png

exece:

#include <t_stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>

int main(void){
    char *p_envp[]={"user=root","caption=beijing",NULL};
    //创建子进程
    pid_t pid=fork();
    if(pid==-1)E_MSG("fork",-1);
    if(pid==0){//子进程执行的代码
        printf("child process...\n");
        //使用新的映像替换掉从父进程继承来的映像
        //execv("/bin/ps",p_argv);
        //默认情况从父进程继承环境变量列表
        //execlp("env","env",NULL);
        //使用带字母e的exec(3)家族的函数
        //可以使用新的环境变量列表替换掉从父进程继承的
        execle("/bin/env","env",NULL,p_envp);
        perror("execvp");
        exit(0);
    }else{//父进程执行的代码
        wait(NULL);//阻塞等待回收子进程的资源
        printf("parent process...\n");
    }
    return 0;
}

运行结果:

TIM截图20190805235650.png


二、myshell

bash命令分为两类
内部命令   外部命令
如果这个命令和bash是两个可执行程序,那这个命令就是外部命令
如果这个命令是bash程序的一部分,这个命令就是内部命令
type  command
外部命令的执行   bash-->fork(2)-->exec(外部命令)
内部命令的执行   bash


演示代码:


运行结果:

版权声明:若无特殊注明,本文皆为《 8964CN 》原创,转载请保留文章出处。
本文链接:[学习笔记]达内纪录片day25 更新进程映像与编写自己的shell http://www.8964cn.net/?post=87
正文到此结束

热门推荐

发表吐槽

你肿么看?

你还可以输入 250 / 250 个字

嘻嘻 大笑 可怜 吃惊 害羞 调皮 鄙视 示爱 大哭 开心 偷笑 嘘 奸笑 委屈 抱抱 愤怒 思考 日了狗 胜利 不高兴 阴险 乖 酷 滑稽

评论信息框

吃奶的力气提交吐槽中...


既然没有吐槽,那就赶紧抢沙发吧!