在写shell之前我们需要先明白以下内容在进行写shell之前要明白shell的基本原理:
,在实现shell的过程中,我们需要循环以下的过程:
1、获取命令行
2、解析命令行
3、建立一个子进程(fork)
4、替换子进程(execvp)
5、父进程等待子进程的退出(wait)
根据这些思路以及我们之前学的技术,就可以来实现自己的shell了。
linux系统中的shell最常见的就是BASH,可以使用以下几种方法查看当前用户使用的shell
echo $SHELL
env | grep SHELL// SHELL是指当前用户用的是哪种Shell是一个环境变量
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
char *argv[8]; //命令行最多有8个参数
int argc=0;
void do_parse(char *buf) //命令行参数的处理
{
int i;
int status=0;
for(argc=i=0;buf[i];i++)
{
if(!isspace(buf[i]) &&status==0){ //将buf中第一个字符地址给argv[argc++],然后stutas置位,直到遇到空格后的下个参数,再将其字符起始地址赋给argv[]
argv[argc++]=buf+i;
status=1;//标志一个参数字符串还没有结束ststus=0标志当前命令行字符为空格
}
else if(isspace(buf[i]) ) {
status=0;
buf[i]=0;
}
}
argv[argc]=NULL;
}
void do_execute(void)
{
pid_t pid=fork();
switch(pid)
{
case -1:
perror("fork");//子进程创建失败
exit(EXIT_FAILURE);break;//子进程替换,fork给子进程返回0
case 0:execvp(argv[0],argv);//数组形式参数,自动检索环境变量perror("execvp");//进程替换成功不返回,直接从替换进程处结束,如果运行到这里,说明进程替换失败,打印提示信息exit(EXIT_FAILURE);default: { int st; while(wait(&st)!=pid) //阻塞等待子进程 ; } }}int main(void){ char buf[1024]={}; while(1) {printf("myshell> ");scanf("%[^\n]%*c",buf);do_parse(buf);do_execute(); }}
这是我实现的myshell,有些命令暂时是无法实现的,后期随着不断的学习,会继续改进的。