编写一个简单的shell

Shell实现代码

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<ctype.h>
#include<pwd.h>
#include<string.h>


void GetLoginName()
{
    struct passwd* pass;
    pass = getpwuid(getuid());
    printf("[%s@",pass->pw_name);   
}

void GetHostName()
{
    char name[128];
    gethostname(name,sizeof(name)-1);
    printf("%s",name);  
}

void GetDir()
{
    char pwd[128];
    getcwd(pwd,sizeof(pwd)-1);
    int len = strlen(pwd);
    char *p = pwd+len-1;
    while(*p !='/' && len--)
        {
            p--;    
        }
        p++;
        printf(" %s]#",p);
}
int main()
{
    while(1)
    {
        GetLoginName();
        GetHostName();
        GetDir();
        fflush(stdout);
        char buf[1024];
        size_t s=read(0,buf,sizeof(buf)-1);
        if(s>0)
        {
            buf[s-1] = 0;
            //printf("%s\n",buf);
        }
        char *_argv[32];
        char *start = buf;
        _argv[0] = start;
        int i = 1;
        while(*start)
        {
            if(*start == ' ')
            {
                *start = '\0';
                start++;
                _argv[i++] = start;
            }
            else
            {
                start++;
            }
        }
        _argv[i] = NULL;

        pid_t id = fork();
        if(id ==0)
        {
            execvp(_argv[0],_argv);
            perror("Perror!");
                exit(1);
        }   
        else 
        {
            int status = 0;
            pid_t ret = waitpid(id,NULL,0);
            if(ret > 0)
            {
                printf("wait success,ret:%d,exitcode:%d,sig:%d\n",\
                    ret,(status>>8)&0xff,status&0xff);
            }
        }
    }
    return 0;

读取命令分析图:
这里写图片描述
水平有限,首先拿到read()函数所读取到的命令。

ssize_t read(int fd, void *buf, size_t count);

这里是read()函数的原型,上面的代码我们用到了size_t s=read(0,buf,sizeof(buf)-1);
可以看到第一个参数为文件标识符,0对应的是输入流,所以我们可以拿到在命令行输入的字符串。

实现shell的机理是利用进程程序替换。这里写图片描述
这里简单说一下这几个函数的区别,
p(path):则第一个参数为路径。
l(list):即把每个命令都当做参数传递。
v(vector):通过指向各参数的指针数组来传递命令。
e(environment):可以传递新的环境变量
这里需要注意的是,l和v不可能同时出现,对于l来说最后一个参数必须为NULL,对于v来说,数组中最后一个指针必须是NULL。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值